From e4fdee8e3b41239242a8f421a28736ef8e08ca55 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 11 May 2005 11:34:32 -0700 Subject: [SUNSAB]: Defer register updates until transmitter is idle. The chip can emit garbage characters if we touch the settings while characters are going out. Signed-off-by: David S. Miller --- drivers/serial/sunsab.c | 109 +++++++++++++++++++++++++++++++----------------- drivers/serial/sunsab.h | 1 + 2 files changed, 72 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 39b788d95e39..10e2990a40d4 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -61,6 +61,16 @@ struct uart_sunsab_port { unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ int type; /* SAB82532 version */ + + /* Setting configuration bits while the transmitter is active + * can cause garbage characters to get emitted by the chip. + * Therefore, we cache such writes here and do the real register + * write the next time the transmitter becomes idle. + */ + unsigned int cached_ebrg; + unsigned char cached_mode; + unsigned char cached_pvr; + unsigned char cached_dafo; }; /* @@ -236,6 +246,7 @@ receive_chars(struct uart_sunsab_port *up, } static void sunsab_stop_tx(struct uart_port *, unsigned int); +static void sunsab_tx_idle(struct uart_sunsab_port *); static void transmit_chars(struct uart_sunsab_port *up, union sab82532_irq_status *stat) @@ -258,6 +269,7 @@ static void transmit_chars(struct uart_sunsab_port *up, return; set_bit(SAB82532_XPR, &up->irqflags); + sunsab_tx_idle(up); if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { up->interrupt_mask1 |= SAB82532_IMR1_XPR; @@ -397,21 +409,21 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; if (mctrl & TIOCM_RTS) { - writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FRTS, - &up->regs->rw.mode); - writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, - &up->regs->rw.mode); + up->cached_mode &= ~SAB82532_MODE_FRTS; + up->cached_mode |= SAB82532_MODE_RTS; } else { - writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS, - &up->regs->rw.mode); - writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, - &up->regs->rw.mode); + up->cached_mode |= (SAB82532_MODE_FRTS | + SAB82532_MODE_RTS); } if (mctrl & TIOCM_DTR) { - writeb(readb(&up->regs->rw.pvr) & ~(up->pvr_dtr_bit), &up->regs->rw.pvr); + up->cached_pvr &= ~(up->pvr_dtr_bit); } else { - writeb(readb(&up->regs->rw.pvr) | up->pvr_dtr_bit, &up->regs->rw.pvr); + up->cached_pvr |= up->pvr_dtr_bit; } + + set_bit(SAB82532_REGS_PENDING, &up->irqflags); + if (test_bit(SAB82532_XPR, &up->irqflags)) + sunsab_tx_idle(up); } /* port->lock is not held. */ @@ -449,6 +461,25 @@ static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop) writeb(up->interrupt_mask1, &up->regs->w.imr1); } +/* port->lock held by caller. */ +static void sunsab_tx_idle(struct uart_sunsab_port *up) +{ + if (test_bit(SAB82532_REGS_PENDING, &up->irqflags)) { + u8 tmp; + + clear_bit(SAB82532_REGS_PENDING, &up->irqflags); + writeb(up->cached_mode, &up->regs->rw.mode); + writeb(up->cached_pvr, &up->regs->rw.pvr); + writeb(up->cached_dafo, &up->regs->w.dafo); + + writeb(up->cached_ebrg & 0xff, &up->regs->w.bgr); + tmp = readb(&up->regs->rw.ccr2); + tmp &= ~0xc0; + tmp |= (up->cached_ebrg >> 2) & 0xc0; + writeb(tmp, &up->regs->rw.ccr2); + } +} + /* port->lock held by caller. */ static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) { @@ -517,12 +548,16 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) spin_lock_irqsave(&up->port.lock, flags); - val = readb(&up->regs->rw.dafo); + val = up->cached_dafo; if (break_state) val |= SAB82532_DAFO_XBRK; else val &= ~SAB82532_DAFO_XBRK; - writeb(val, &up->regs->rw.dafo); + up->cached_dafo = val; + + set_bit(SAB82532_REGS_PENDING, &up->irqflags); + if (test_bit(SAB82532_XPR, &up->irqflags)) + sunsab_tx_idle(up); spin_unlock_irqrestore(&up->port.lock, flags); } @@ -566,8 +601,9 @@ static int sunsab_startup(struct uart_port *port) SAB82532_CCR2_TOE, &up->regs->w.ccr2); writeb(0, &up->regs->w.ccr3); writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4); - writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS | - SAB82532_MODE_RAC, &up->regs->w.mode); + up->cached_mode = (SAB82532_MODE_RTS | SAB82532_MODE_FCTS | + SAB82532_MODE_RAC); + writeb(up->cached_mode, &up->regs->w.mode); writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc); tmp = readb(&up->regs->rw.ccr0); @@ -598,7 +634,6 @@ static void sunsab_shutdown(struct uart_port *port) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; unsigned long flags; - unsigned char tmp; spin_lock_irqsave(&up->port.lock, flags); @@ -609,14 +644,13 @@ static void sunsab_shutdown(struct uart_port *port) writeb(up->interrupt_mask1, &up->regs->w.imr1); /* Disable break condition */ - tmp = readb(&up->regs->rw.dafo); - tmp &= ~SAB82532_DAFO_XBRK; - writeb(tmp, &up->regs->rw.dafo); + up->cached_dafo = readb(&up->regs->rw.dafo); + up->cached_dafo &= ~SAB82532_DAFO_XBRK; + writeb(up->cached_dafo, &up->regs->rw.dafo); /* Disable Receiver */ - tmp = readb(&up->regs->rw.mode); - tmp &= ~SAB82532_MODE_RAC; - writeb(tmp, &up->regs->rw.mode); + up->cached_mode &= ~SAB82532_MODE_RAC; + writeb(up->cached_mode, &up->regs->rw.mode); /* * XXX FIXME @@ -685,7 +719,6 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla unsigned int iflag, unsigned int baud, unsigned int quot) { - unsigned int ebrg; unsigned char dafo; int bits, n, m; @@ -714,10 +747,11 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla } else { dafo |= SAB82532_DAFO_PAR_EVEN; } + up->cached_dafo = dafo; calc_ebrg(baud, &n, &m); - ebrg = n | (m << 6); + up->cached_ebrg = n | (m << 6); up->tec_timeout = (10 * 1000000) / baud; up->cec_timeout = up->tec_timeout >> 2; @@ -770,16 +804,13 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla uart_update_timeout(&up->port, cflag, (up->port.uartclk / (16 * quot))); - /* Now bang the new settings into the chip. */ - sunsab_cec_wait(up); - sunsab_tec_wait(up); - writeb(dafo, &up->regs->w.dafo); - writeb(ebrg & 0xff, &up->regs->w.bgr); - writeb((readb(&up->regs->rw.ccr2) & ~0xc0) | ((ebrg >> 2) & 0xc0), - &up->regs->rw.ccr2); - - writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RAC, &up->regs->rw.mode); - + /* Now schedule a register update when the chip's + * transmitter is idle. + */ + up->cached_mode |= SAB82532_MODE_RAC; + set_bit(SAB82532_REGS_PENDING, &up->irqflags); + if (test_bit(SAB82532_XPR, &up->irqflags)) + sunsab_tx_idle(up); } /* port->lock is not held. */ @@ -1084,11 +1115,13 @@ static void __init sunsab_init_hw(void) up->pvr_dsr_bit = (1 << 3); up->pvr_dtr_bit = (1 << 2); } - writeb((1 << 1) | (1 << 2) | (1 << 4), &up->regs->w.pvr); - writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS, - &up->regs->rw.mode); - writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, - &up->regs->rw.mode); + up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4); + writeb(up->cached_pvr, &up->regs->w.pvr); + up->cached_mode = readb(&up->regs->rw.mode); + up->cached_mode |= SAB82532_MODE_FRTS; + writeb(up->cached_mode, &up->regs->rw.mode); + up->cached_mode |= SAB82532_MODE_RTS; + writeb(up->cached_mode, &up->regs->rw.mode); up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; diff --git a/drivers/serial/sunsab.h b/drivers/serial/sunsab.h index 686086fcbbf5..b78e1f7b8050 100644 --- a/drivers/serial/sunsab.h +++ b/drivers/serial/sunsab.h @@ -126,6 +126,7 @@ union sab82532_irq_status { /* irqflags bits */ #define SAB82532_ALLS 0x00000001 #define SAB82532_XPR 0x00000002 +#define SAB82532_REGS_PENDING 0x00000004 /* RFIFO Status Byte */ #define SAB82532_RSTAT_PE 0x80 -- cgit v1.2.2 From dfa1b73ffb414b64dc0452260132a090eb25bf52 Mon Sep 17 00:00:00 2001 From: Liu Tao Date: Thu, 12 May 2005 19:40:38 -0400 Subject: [PATCH] drivers/net/amd8111e.c: fix NAPI interrupt in poll This patch makes the netif_rx_complete() and rx_interrupt_enable atomic when exiting the poll() method, so to avoid interrupt in poll. It also fixes the rx interrupt check logic in interrupt handler. Signed-off-by: Liu Tao Signed-off-by: Jeff Garzik --- drivers/net/amd8111e.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index f2e937abf7b4..b7dd7260cafb 100755 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -738,6 +738,7 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget) short vtag; #endif int rx_pkt_limit = dev->quota; + unsigned long flags; do{ /* process receive packets until we use the quota*/ @@ -841,18 +842,19 @@ static int amd8111e_rx_poll(struct net_device *dev, int * budget) /* Receive descriptor is empty now */ dev->quota -= num_rx_pkt; *budget -= num_rx_pkt; + + spin_lock_irqsave(&lp->lock, flags); netif_rx_complete(dev); - /* enable receive interrupt */ writel(VAL0|RINTEN0, mmio + INTEN0); writel(VAL2 | RDMD0, mmio + CMD0); + spin_unlock_irqrestore(&lp->lock, flags); return 0; + rx_not_empty: /* Do not call a netif_rx_complete */ dev->quota -= num_rx_pkt; *budget -= num_rx_pkt; return 1; - - } #else @@ -1261,18 +1263,20 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg struct net_device * dev = (struct net_device *) dev_id; struct amd8111e_priv *lp = netdev_priv(dev); void __iomem *mmio = lp->mmio; - unsigned int intr0; + unsigned int intr0, intren0; unsigned int handled = 1; - if(dev == NULL) + if(unlikely(dev == NULL)) return IRQ_NONE; - if (regs) spin_lock (&lp->lock); + spin_lock(&lp->lock); + /* disabling interrupt */ writel(INTREN, mmio + CMD0); /* Read interrupt status */ intr0 = readl(mmio + INT0); + intren0 = readl(mmio + INTEN0); /* Process all the INT event until INTR bit is clear. */ @@ -1293,11 +1297,11 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg /* Schedule a polling routine */ __netif_rx_schedule(dev); } - else { + else if (intren0 & RINTEN0) { printk("************Driver bug! \ interrupt while in poll\n"); - /* Fix by disabling interrupts */ - writel(RINT0, mmio + INT0); + /* Fix by disable receive interrupts */ + writel(RINTEN0, mmio + INTEN0); } } #else @@ -1321,7 +1325,7 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id, struct pt_regs *reg err_no_interrupt: writel( VAL0 | INTREN,mmio + CMD0); - if (regs) spin_unlock(&lp->lock); + spin_unlock(&lp->lock); return IRQ_RETVAL(handled); } -- cgit v1.2.2 From 2918c35d311263bc313b3da272783860ce573189 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Thu, 12 May 2005 19:42:06 -0400 Subject: [PATCH] forcedeth: netpoll support --- drivers/net/forcedeth.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index cda48c5d72a9..c93f3d08dc42 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -1480,6 +1480,13 @@ static void nv_do_nic_poll(unsigned long data) enable_irq(dev->irq); } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void nv_poll_controller(struct net_device *dev) +{ + nv_do_nic_poll((unsigned long) dev); +} +#endif + static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { struct fe_priv *np = get_nvpriv(dev); @@ -1962,6 +1969,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->get_stats = nv_get_stats; dev->change_mtu = nv_change_mtu; dev->set_multicast_list = nv_set_multicast; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = nv_poll_controller; +#endif SET_ETHTOOL_OPS(dev, &ops); dev->tx_timeout = nv_tx_timeout; dev->watchdog_timeo = NV_WATCHDOG_TIMEO; -- cgit v1.2.2 From da369b01d49b34803265096eb92a2d6da61cf0d0 Mon Sep 17 00:00:00 2001 From: Daniele Venzano Date: Thu, 12 May 2005 20:13:14 -0400 Subject: [PATCH] More ethtool support for sis900 and warning fix Add support to sis900 for the following ethtool ops: - get_link - get_settings - set_settings - nway_reset Signed-off-by: Daniele Venzano Signed-off-by: Jeff Garzik --- drivers/net/sis900.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 3e9d9aab0588..3107aed0fb51 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -162,6 +162,7 @@ struct sis900_private { struct mii_phy * mii; struct mii_phy * first_mii; /* record the first mii structure */ unsigned int cur_phy; + struct mii_if_info mii_info; struct timer_list timer; /* Link status detection timer. */ u8 autong_complete; /* 1: auto-negotiate complete */ @@ -203,7 +204,7 @@ static int sis900_open(struct net_device *net_dev); static int sis900_mii_probe (struct net_device * net_dev); static void sis900_init_rxfilter (struct net_device * net_dev); static u16 read_eeprom(long ioaddr, int location); -static u16 mdio_read(struct net_device *net_dev, int phy_id, int location); +static int mdio_read(struct net_device *net_dev, int phy_id, int location); static void mdio_write(struct net_device *net_dev, int phy_id, int location, int val); static void sis900_timer(unsigned long data); static void sis900_check_mode (struct net_device *net_dev, struct mii_phy *mii_phy); @@ -478,7 +479,13 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev, sis_priv->msg_enable = sis900_debug; else sis_priv->msg_enable = SIS900_DEF_MSG; - + + sis_priv->mii_info.dev = net_dev; + sis_priv->mii_info.mdio_read = mdio_read; + sis_priv->mii_info.mdio_write = mdio_write; + sis_priv->mii_info.phy_id_mask = 0x1f; + sis_priv->mii_info.reg_num_mask = 0x1f; + /* Get Mac address according to the chip revision */ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &(sis_priv->chipset_rev)); if(netif_msg_probe(sis_priv)) @@ -725,6 +732,8 @@ static u16 sis900_default_phy(struct net_device * net_dev) pci_name(sis_priv->pci_dev), sis_priv->cur_phy); } + sis_priv->mii_info.phy_id = sis_priv->cur_phy; + status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL); status &= (~MII_CNTL_ISOLATE); @@ -852,7 +861,7 @@ static void mdio_reset(long mdio_addr) * Please see SiS7014 or ICS spec */ -static u16 mdio_read(struct net_device *net_dev, int phy_id, int location) +static int mdio_read(struct net_device *net_dev, int phy_id, int location) { long mdio_addr = net_dev->base_addr + mear; int mii_cmd = MIIread|(phy_id<msg_enable = value; } +static u32 sis900_get_link(struct net_device *net_dev) +{ + struct sis900_private *sis_priv = net_dev->priv; + return mii_link_ok(&sis_priv->mii_info); +} + +static int sis900_get_settings(struct net_device *net_dev, + struct ethtool_cmd *cmd) +{ + struct sis900_private *sis_priv = net_dev->priv; + spin_lock_irq(&sis_priv->lock); + mii_ethtool_gset(&sis_priv->mii_info, cmd); + spin_unlock_irq(&sis_priv->lock); + return 0; +} + +static int sis900_set_settings(struct net_device *net_dev, + struct ethtool_cmd *cmd) +{ + struct sis900_private *sis_priv = net_dev->priv; + int rt; + spin_lock_irq(&sis_priv->lock); + rt = mii_ethtool_sset(&sis_priv->mii_info, cmd); + spin_unlock_irq(&sis_priv->lock); + return rt; +} + +static int sis900_nway_reset(struct net_device *net_dev) +{ + struct sis900_private *sis_priv = net_dev->priv; + return mii_nway_restart(&sis_priv->mii_info); +} + static struct ethtool_ops sis900_ethtool_ops = { .get_drvinfo = sis900_get_drvinfo, .get_msglevel = sis900_get_msglevel, .set_msglevel = sis900_set_msglevel, + .get_link = sis900_get_link, + .get_settings = sis900_get_settings, + .set_settings = sis900_set_settings, + .nway_reset = sis900_nway_reset, }; /** -- cgit v1.2.2 From e4eff7291c977308989b24fdfc7215a501302e6a Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:38:30 -0700 Subject: [PATCH] e1000: made loopback test robust Added enhanced functionality to the loopback diags to wrap the descriptor rings. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_ethtool.c net-drivers-2.6/drivers/net/e1000.new/e1000_ethtool.c --- drivers/net/e1000/e1000_ethtool.c | 81 ++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index 0a2ca7c73a41..fae585453463 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -919,7 +919,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) /* Setup Tx descriptor ring and Tx buffers */ - txdr->count = 80; + if(!txdr->count) + txdr->count = E1000_DEFAULT_TXD; size = txdr->count * sizeof(struct e1000_buffer); if(!(txdr->buffer_info = kmalloc(size, GFP_KERNEL))) { @@ -974,7 +975,8 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) /* Setup Rx descriptor ring and Rx buffers */ - rxdr->count = 80; + if(!rxdr->count) + rxdr->count = E1000_DEFAULT_RXD; size = rxdr->count * sizeof(struct e1000_buffer); if(!(rxdr->buffer_info = kmalloc(size, GFP_KERNEL))) { @@ -1310,31 +1312,62 @@ e1000_run_loopback_test(struct e1000_adapter *adapter) struct e1000_desc_ring *txdr = &adapter->test_tx_ring; struct e1000_desc_ring *rxdr = &adapter->test_rx_ring; struct pci_dev *pdev = adapter->pdev; - int i, ret_val; + int i, j, k, l, lc, good_cnt, ret_val=0; + unsigned long time; E1000_WRITE_REG(&adapter->hw, RDT, rxdr->count - 1); - for(i = 0; i < 64; i++) { - e1000_create_lbtest_frame(txdr->buffer_info[i].skb, 1024); - pci_dma_sync_single_for_device(pdev, txdr->buffer_info[i].dma, - txdr->buffer_info[i].length, - PCI_DMA_TODEVICE); - } - E1000_WRITE_REG(&adapter->hw, TDT, i); - - msec_delay(200); - - i = 0; - do { - pci_dma_sync_single_for_cpu(pdev, rxdr->buffer_info[i].dma, - rxdr->buffer_info[i].length, - PCI_DMA_FROMDEVICE); - - ret_val = e1000_check_lbtest_frame(rxdr->buffer_info[i].skb, - 1024); - i++; - } while (ret_val != 0 && i < 64); + /* Calculate the loop count based on the largest descriptor ring + * The idea is to wrap the largest ring a number of times using 64 + * send/receive pairs during each loop + */ + if(rxdr->count <= txdr->count) + lc = ((txdr->count / 64) * 2) + 1; + else + lc = ((rxdr->count / 64) * 2) + 1; + + k = l = 0; + for(j = 0; j <= lc; j++) { /* loop count loop */ + for(i = 0; i < 64; i++) { /* send the packets */ + e1000_create_lbtest_frame(txdr->buffer_info[i].skb, + 1024); + pci_dma_sync_single_for_device(pdev, + txdr->buffer_info[k].dma, + txdr->buffer_info[k].length, + PCI_DMA_TODEVICE); + if(unlikely(++k == txdr->count)) k = 0; + } + E1000_WRITE_REG(&adapter->hw, TDT, k); + msec_delay(200); + time = jiffies; /* set the start time for the receive */ + good_cnt = 0; + do { /* receive the sent packets */ + pci_dma_sync_single_for_cpu(pdev, + rxdr->buffer_info[l].dma, + rxdr->buffer_info[l].length, + PCI_DMA_FROMDEVICE); + + ret_val = e1000_check_lbtest_frame( + rxdr->buffer_info[l].skb, + 1024); + if(!ret_val) + good_cnt++; + if(unlikely(++l == rxdr->count)) l = 0; + /* time + 20 msecs (200 msecs on 2.4) is more than + * enough time to complete the receives, if it's + * exceeded, break and error off + */ + } while (good_cnt < 64 && jiffies < (time + 20)); + if(good_cnt != 64) { + ret_val = 13; /* ret_val is the same as mis-compare */ + break; + } + if(jiffies >= (time + 2)) { + ret_val = 14; /* error code for time out error */ + break; + } + } /* end loop count loop */ return ret_val; } @@ -1371,6 +1404,8 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) *data = 1; } else { e1000_check_for_link(&adapter->hw); + if(adapter->hw.autoneg) /* if auto_neg is set wait for it */ + msec_delay(4000); if(!(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU)) { *data = 1; -- cgit v1.2.2 From df25e164878836196ee93d1a5757867da6eac30e Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:38:43 -0700 Subject: [PATCH] e1000: Fix msec-delay definition to use msleep Fix msec-delay definition in e1000_osdep.h to use msleep Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_osdep.h net-drivers-2.6/drivers/net/e1000.new/e1000_osdep.h --- drivers/net/e1000/e1000_osdep.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 970c656a517c..2efa3b1b64dc 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -42,7 +42,12 @@ #include #ifndef msec_delay -#define msec_delay(x) msleep(x) +#define msec_delay(x) do { if(in_interrupt()) { \ + /* Don't mdelay in interrupt context! */ \ + BUG(); \ + } else { \ + msleep(x); \ + } } while(0) /* Some workarounds require millisecond delays and are run during interrupt * context. Most notably, when establishing link, the phy may need tweaking -- cgit v1.2.2 From fa4f7ef3aaa6cee6b04ebe90266ee893e0b2ce07 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:39:13 -0700 Subject: [PATCH] e1000: MSI support for PCI-e adapters MSI support for PCI-e adapters Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000.h net-drivers-2.6/drivers/net/e1000.new/e1000.h --- drivers/net/e1000/e1000.h | 3 +++ drivers/net/e1000/e1000_main.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 148930d4e9bd..da055520daa0 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -257,5 +257,8 @@ struct e1000_adapter { int msg_enable; +#ifdef CONFIG_PCI_MSI + boolean_t have_msi; +#endif }; #endif /* _E1000_H_ */ diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 82549a6fcfb3..03e3ec74f3fb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -312,6 +312,16 @@ e1000_up(struct e1000_adapter *adapter) e1000_configure_rx(adapter); e1000_alloc_rx_buffers(adapter); +#ifdef CONFIG_PCI_MSI + if(adapter->hw.mac_type > e1000_82547_rev_2) { + adapter->have_msi = TRUE; + if((err = pci_enable_msi(adapter->pdev))) { + DPRINTK(PROBE, ERR, + "Unable to allocate MSI interrupt Error: %d\n", err); + adapter->have_msi = FALSE; + } + } +#endif if((err = request_irq(adapter->pdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name, netdev))) @@ -333,6 +343,11 @@ e1000_down(struct e1000_adapter *adapter) e1000_irq_disable(adapter); free_irq(adapter->pdev->irq, netdev); +#ifdef CONFIG_PCI_MSI + if(adapter->hw.mac_type > e1000_82547_rev_2 && + adapter->have_msi == TRUE) + pci_disable_msi(adapter->pdev); +#endif del_timer_sync(&adapter->tx_fifo_stall_timer); del_timer_sync(&adapter->watchdog_timer); del_timer_sync(&adapter->phy_info_timer); -- cgit v1.2.2 From 5de556249fde97493a4c79dbf8979ace0f76789f Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:39:30 -0700 Subject: [PATCH] e1000: Enable polling before enabling interrupts Enable polling before enabling interrupts -- avoids (in NAPI mode) entering the ISR and returning without doing any work because polling is not enabled. [romieu@fr.zoriel.com] Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 03e3ec74f3fb..9927106b76c7 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -328,11 +328,12 @@ e1000_up(struct e1000_adapter *adapter) return err; mod_timer(&adapter->watchdog_timer, jiffies); - e1000_irq_enable(adapter); #ifdef CONFIG_E1000_NAPI netif_poll_enable(netdev); #endif + e1000_irq_enable(adapter); + return 0; } -- cgit v1.2.2 From 4e48a2b91d408357cb0747151d8db5368ac8f1d0 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:39:53 -0700 Subject: [PATCH] e1000: Fix kernel panic with 82541 LOM Fix kernel panic with 82541 LOM when using a 100M cable Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 9927106b76c7..9c6c1fbbc412 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -372,6 +372,7 @@ e1000_down(struct e1000_adapter *adapter) e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; e1000_write_phy_reg(&adapter->hw, PHY_CTRL, mii_reg); + mdelay(1); } } -- cgit v1.2.2 From 2701234fc0372630457e3da14e36cde53c57d12e Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:40:28 -0700 Subject: [PATCH] e1000: Delay clean-up of last Tx packet Delay clean-up of last Tx packet to fix pre-mature writeback issue of Tx descriptors only when TSO is enabled Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 43 ++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 9c6c1fbbc412..4a8c069e6c7c 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2384,11 +2384,10 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) eop_desc = E1000_TX_DESC(*tx_ring, eop); while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) { - /* pre-mature writeback of Tx descriptors */ - /* clear (free buffers and unmap pci_mapping) */ - /* previous_buffer_info */ + /* Premature writeback of Tx descriptors clear (free buffers + * and unmap pci_mapping) previous_buffer_info */ if (likely(adapter->previous_buffer_info.skb != NULL)) { - e1000_unmap_and_free_tx_resource(adapter, + e1000_unmap_and_free_tx_resource(adapter, &adapter->previous_buffer_info); } @@ -2397,20 +2396,25 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) buffer_info = &tx_ring->buffer_info[i]; cleaned = (i == eop); - /* pre-mature writeback of Tx descriptors */ - /* save the cleaning of the this for the */ - /* next iteration */ - if (cleaned) { - memcpy(&adapter->previous_buffer_info, - buffer_info, - sizeof(struct e1000_buffer)); - memset(buffer_info, - 0, - sizeof(struct e1000_buffer)); +#ifdef NETIF_F_TSO + if (!(netdev->features & NETIF_F_TSO)) { +#endif + e1000_unmap_and_free_tx_resource(adapter, + buffer_info); +#ifdef NETIF_F_TSO } else { - e1000_unmap_and_free_tx_resource(adapter, - buffer_info); + if (cleaned) { + memcpy(&adapter->previous_buffer_info, + buffer_info, + sizeof(struct e1000_buffer)); + memset(buffer_info, 0, + sizeof(struct e1000_buffer)); + } else { + e1000_unmap_and_free_tx_resource( + adapter, buffer_info); + } } +#endif tx_desc->buffer_addr = 0; tx_desc->lower.data = 0; @@ -2443,7 +2447,14 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) netif_stop_queue(netdev); } +#ifdef NETIF_F_TSO + if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) && + time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ))) + e1000_unmap_and_free_tx_resource( + adapter, &adapter->previous_buffer_info); + +#endif return cleaned; } -- cgit v1.2.2 From 70b8f1e16a788eccdd36f39679774b1a08a6ba55 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:40:40 -0700 Subject: [PATCH] e1000: Dump information on Tx ring Dump information on Tx ring when 'NETDEV: Watchdog' condition is reached Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4a8c069e6c7c..b5811f4f88f0 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2442,10 +2442,37 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) /* detect a transmit hang in hardware, this serializes the * check with the clearing of time_stamp and movement of i */ adapter->detect_tx_hung = FALSE; - if(tx_ring->buffer_info[i].dma && - time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) && - !(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_TXOFF)) + if (tx_ring->buffer_info[i].dma && + time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) + && !(E1000_READ_REG(&adapter->hw, STATUS) & + E1000_STATUS_TXOFF)) { + + /* detected Tx unit hang */ + i = tx_ring->next_to_clean; + eop = tx_ring->buffer_info[i].next_to_watch; + eop_desc = E1000_TX_DESC(*tx_ring, eop); + DPRINTK(TX_ERR, ERR, "Detected Tx Unit Hang\n" + " TDH <%x>\n" + " TDT <%x>\n" + " next_to_use <%x>\n" + " next_to_clean <%x>\n" + "buffer_info[next_to_clean]\n" + " dma <%llx>\n" + " time_stamp <%lx>\n" + " next_to_watch <%x>\n" + " jiffies <%lx>\n" + " next_to_watch.status <%x>\n", + E1000_READ_REG(&adapter->hw, TDH), + E1000_READ_REG(&adapter->hw, TDT), + tx_ring->next_to_use, + i, + tx_ring->buffer_info[i].dma, + tx_ring->buffer_info[i].time_stamp, + eop, + jiffies, + eop_desc->upper.fields.status); netif_stop_queue(netdev); + } } #ifdef NETIF_F_TSO -- cgit v1.2.2 From 6d9157577d926d2a83fe8d4914c0cc216deb5842 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:41:11 -0700 Subject: [PATCH] e1000:Fix computation of netdev stats from controller stats counters Fix computation of netdev stats from controller stats counters - from sfeldma@pobox.com Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index b5811f4f88f0..ed1e57ac7554 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2230,9 +2230,9 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->net_stats.rx_errors = adapter->stats.rxerrc + adapter->stats.crcerrs + adapter->stats.algnerrc + - adapter->stats.rlec + adapter->stats.rnbc + - adapter->stats.mpc + adapter->stats.cexterr; - adapter->net_stats.rx_dropped = adapter->stats.rnbc; + adapter->stats.rlec + adapter->stats.mpc + + adapter->stats.cexterr; + adapter->net_stats.rx_dropped = adapter->stats.mpc; adapter->net_stats.rx_length_errors = adapter->stats.rlec; adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc; -- cgit v1.2.2 From a4cb847dac40577dd751a4deb4085ed080780679 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:41:28 -0700 Subject: [PATCH] e1000: e1000 stops working after resume e1000 stops working after resume, call pci_enable_device after pci_restore_state - Modified Andrew Morton's patch Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ed1e57ac7554..479915a9f0fb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3173,8 +3173,7 @@ e1000_resume(struct pci_dev *pdev) pci_set_power_state(pdev, 0); pci_restore_state(pdev); ret = pci_enable_device(pdev); - if (pdev->is_busmaster) - pci_set_master(pdev); + pci_set_master(pdev); pci_enable_wake(pdev, 3, 0); pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ -- cgit v1.2.2 From 97338bde27d97347bc83203d6ac5e93be1ebcd03 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:41:46 -0700 Subject: [PATCH] e1000: Implement a workaround for 82546 errata 10 Implement 82546 errata 10 -- first Tx descriptor cannot have more than 2015 byte of data in it or it could hang the transmitter. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 479915a9f0fb..e54890aff5f1 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1777,6 +1777,15 @@ e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb, if(unlikely(mss && !nr_frags && size == len && size > 8)) size -= 4; #endif + /* work-around for errata 10 and it applies + * to all controllers in PCI-X mode + * The fix is to make sure that the first descriptor of a + * packet is smaller than 2048 - 16 - 16 (or 2016) bytes + */ + if(unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) && + (size > 2015) && count == 0)) + size = 2015; + /* Workaround for potential 82544 hang in PCI-X. Avoid * terminating buffers within evenly-aligned dwords. */ if(unlikely(adapter->pcix_82544 && @@ -1979,6 +1988,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if(adapter->pcix_82544) count++; + /* work-around for errata 10 and it applies to all controllers + * in PCI-X mode, so add one more descriptor to the count + */ + if(unlikely((adapter->hw.bus_type == e1000_bus_type_pcix) && + (len > 2015))) + count++; + nr_frags = skb_shinfo(skb)->nr_frags; for(f = 0; f < nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size, -- cgit v1.2.2 From f1d2e4905eed4b13c3ba56ac6d30c283be996963 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:42:04 -0700 Subject: [PATCH] e1000:Removed redundant statement in e1000_clean_tx_irq Removed redundant statement in e1000_clean_tx_irq Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index e54890aff5f1..0fec670e51ef 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2436,7 +2436,6 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) tx_desc->lower.data = 0; tx_desc->upper.data = 0; - cleaned = (i == eop); if(unlikely(++i == tx_ring->count)) i = 0; } -- cgit v1.2.2 From f0d11ed0b0650d2f93f56f65167c10a577c16c88 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:43:28 -0700 Subject: [PATCH] e1000: Modified e1000_clean: exit poll Modified e1000_clean:: exit poll if no Tx and work_done == 0 Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 0fec670e51ef..4cdf371961eb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2368,9 +2368,8 @@ e1000_clean(struct net_device *netdev, int *budget) *budget -= work_done; netdev->quota -= work_done; - /* if no Tx and not enough Rx work done, exit the polling mode */ - if((!tx_cleaned && (work_done < work_to_do)) || - !netif_running(netdev)) { + /* If no Tx and no Rx work done, exit the polling mode */ + if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { netif_rx_complete(netdev); e1000_irq_enable(adapter); return 0; -- cgit v1.2.2 From 2d7edb923a823660b081bd4c660300ee19adca8d Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:43:52 -0700 Subject: [PATCH] e1000:82573 specific code & packet split code 82573 specific code & packet split code Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000.h net-drivers-2.6/drivers/net/e1000.new/e1000.h --- drivers/net/e1000/e1000.h | 26 + drivers/net/e1000/e1000_hw.c | 2132 ++++++++++++++++++++++++++++++--------- drivers/net/e1000/e1000_hw.h | 568 ++++++++++- drivers/net/e1000/e1000_main.c | 804 ++++++++++++--- drivers/net/e1000/e1000_osdep.h | 23 + 5 files changed, 2956 insertions(+), 597 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index da055520daa0..19858c267532 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -112,6 +112,8 @@ struct e1000_adapter; #define E1000_MAX_82544_RXD 4096 /* Supported Rx Buffer Sizes */ +#define E1000_RXBUFFER_128 128 /* Used for packet split */ +#define E1000_RXBUFFER_256 256 /* Used for packet split */ #define E1000_RXBUFFER_2048 2048 #define E1000_RXBUFFER_4096 4096 #define E1000_RXBUFFER_8192 8192 @@ -146,6 +148,10 @@ struct e1000_adapter; #define E1000_MASTER_SLAVE e1000_ms_hw_default #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 + /* only works for sizes that are powers of 2 */ #define E1000_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) @@ -159,6 +165,9 @@ struct e1000_buffer { uint16_t next_to_watch; }; +struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; }; +struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; }; + struct e1000_desc_ring { /* pointer to the descriptor ring memory */ void *desc; @@ -174,12 +183,19 @@ struct e1000_desc_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; }; #define E1000_DESC_UNUSED(R) \ ((((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])) #define E1000_RX_DESC(R, i) E1000_GET_DESC(R, i, e1000_rx_desc) #define E1000_TX_DESC(R, i) E1000_GET_DESC(R, i, e1000_tx_desc) @@ -192,6 +208,7 @@ struct e1000_adapter { struct timer_list watchdog_timer; struct timer_list phy_info_timer; struct vlan_group *vlgrp; + uint16_t mng_vlan_id; uint32_t bd_number; uint32_t rx_buffer_len; uint32_t part_num; @@ -228,14 +245,23 @@ struct e1000_adapter { boolean_t detect_tx_hung; /* RX */ +#ifdef CONFIG_E1000_NAPI + boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done, + int work_to_do); +#else + boolean_t (*clean_rx) (struct e1000_adapter *adapter); +#endif + void (*alloc_rx_buf) (struct e1000_adapter *adapter); struct e1000_desc_ring rx_ring; uint64_t hw_csum_err; uint64_t hw_csum_good; uint32_t rx_int_delay; uint32_t rx_abs_int_delay; boolean_t rx_csum; + boolean_t rx_ps; uint32_t gorcl; uint64_t gorcl_old; + uint16_t rx_ps_bsize0; /* Interrupt Throttle Rate */ uint32_t itr; diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 786a9b935659..b7a7ceb67f47 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -63,10 +63,11 @@ static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw, uint16_t count); static int32_t e1000_acquire_eeprom(struct e1000_hw *hw); static void e1000_release_eeprom(struct e1000_hw *hw); static void e1000_standby_eeprom(struct e1000_hw *hw); -static int32_t e1000_id_led_init(struct e1000_hw * hw); static int32_t e1000_set_vco_speed(struct e1000_hw *hw); static int32_t e1000_polarity_reversal_workaround(struct e1000_hw *hw); static int32_t e1000_set_phy_mode(struct e1000_hw *hw); +static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer); +static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length); /* IGP cable length table */ static const @@ -80,6 +81,17 @@ uint16_t e1000_igp_cable_length_table[IGP01E1000_AGC_LENGTH_TABLE_SIZE] = 100, 100, 100, 100, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120}; +static const +uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] = + { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, + 22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58, + 32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74, + 43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90, + 57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108, + 73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124, + 91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128, + 108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}; + /****************************************************************************** * Set the phy type member in the hw struct. @@ -91,10 +103,14 @@ e1000_set_phy_type(struct e1000_hw *hw) { DEBUGFUNC("e1000_set_phy_type"); + if(hw->mac_type == e1000_undefined) + return -E1000_ERR_PHY_TYPE; + switch(hw->phy_id) { case M88E1000_E_PHY_ID: case M88E1000_I_PHY_ID: case M88E1011_I_PHY_ID: + case M88E1111_I_PHY_ID: hw->phy_type = e1000_phy_m88; break; case IGP01E1000_I_PHY_ID: @@ -271,6 +287,7 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82546GB_FIBER: case E1000_DEV_ID_82546GB_SERDES: case E1000_DEV_ID_82546GB_PCIE: + case E1000_DEV_ID_82546GB_QUAD_COPPER: hw->mac_type = e1000_82546_rev_3; break; case E1000_DEV_ID_82541EI: @@ -289,12 +306,19 @@ e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82547GI: hw->mac_type = e1000_82547_rev_2; break; + case E1000_DEV_ID_82573E: + case E1000_DEV_ID_82573E_IAMT: + hw->mac_type = e1000_82573; + break; default: /* Should never have loaded on this device */ return -E1000_ERR_MAC_TYPE; } switch(hw->mac_type) { + case e1000_82573: + hw->eeprom_semaphore_present = TRUE; + /* fall through */ case e1000_82541: case e1000_82547: case e1000_82541_rev_2: @@ -360,6 +384,9 @@ e1000_reset_hw(struct e1000_hw *hw) uint32_t icr; uint32_t manc; uint32_t led_ctrl; + uint32_t timeout; + uint32_t extcnf_ctrl; + int32_t ret_val; DEBUGFUNC("e1000_reset_hw"); @@ -369,6 +396,15 @@ e1000_reset_hw(struct e1000_hw *hw) e1000_pci_clear_mwi(hw); } + if(hw->bus_type == e1000_bus_type_pci_express) { + /* Prevent the PCI-E bus from sticking if there is no TLP connection + * on the last TLP read/write transaction when MAC is reset. + */ + if(e1000_disable_pciex_master(hw) != E1000_SUCCESS) { + DEBUGOUT("PCI-E Master disable polling has failed.\n"); + } + } + /* Clear interrupt mask to stop board from generating interrupts */ DEBUGOUT("Masking off all interrupts\n"); E1000_WRITE_REG(hw, IMC, 0xffffffff); @@ -393,10 +429,32 @@ e1000_reset_hw(struct e1000_hw *hw) /* Must reset the PHY before resetting the MAC */ if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { - E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); + E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST)); msec_delay(5); } + /* Must acquire the MDIO ownership before MAC reset. + * Ownership defaults to firmware after a reset. */ + if(hw->mac_type == e1000_82573) { + timeout = 10; + + extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + do { + E1000_WRITE_REG(hw, EXTCNF_CTRL, extcnf_ctrl); + extcnf_ctrl = E1000_READ_REG(hw, EXTCNF_CTRL); + + if(extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) + break; + else + extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; + + msec_delay(2); + timeout--; + } while(timeout); + } + /* Issue a global reset to the MAC. This will reset the chip's * transmit, receive, DMA, and link units. It will not effect * the current PCI configuration. The global reset bit is self- @@ -450,6 +508,18 @@ e1000_reset_hw(struct e1000_hw *hw) /* Wait for EEPROM reload */ msec_delay(20); break; + case e1000_82573: + udelay(10); + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_EE_RST; + E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); + E1000_WRITE_FLUSH(hw); + /* fall through */ + ret_val = e1000_get_auto_rd_done(hw); + if(ret_val) + /* We don't want to continue accessing MAC registers. */ + return ret_val; + break; default: /* Wait for EEPROM reload (it happens automatically) */ msec_delay(5); @@ -457,7 +527,7 @@ e1000_reset_hw(struct e1000_hw *hw) } /* Disable HW ARPs on ASF enabled adapters */ - if(hw->mac_type >= e1000_82540) { + if(hw->mac_type >= e1000_82540 && hw->mac_type <= e1000_82547_rev_2) { manc = E1000_READ_REG(hw, MANC); manc &= ~(E1000_MANC_ARP_EN); E1000_WRITE_REG(hw, MANC, manc); @@ -510,6 +580,8 @@ e1000_init_hw(struct e1000_hw *hw) uint16_t pcix_stat_hi_word; uint16_t cmd_mmrbc; uint16_t stat_mmrbc; + uint32_t mta_size; + DEBUGFUNC("e1000_init_hw"); /* Initialize Identification LED */ @@ -524,8 +596,8 @@ e1000_init_hw(struct e1000_hw *hw) /* Disabling VLAN filtering. */ DEBUGOUT("Initializing the IEEE VLAN\n"); - E1000_WRITE_REG(hw, VET, 0); - + if (hw->mac_type < e1000_82545_rev_3) + E1000_WRITE_REG(hw, VET, 0); e1000_clear_vfta(hw); /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ @@ -553,14 +625,16 @@ e1000_init_hw(struct e1000_hw *hw) /* Zero out the Multicast HASH table */ DEBUGOUT("Zeroing the MTA\n"); - for(i = 0; i < E1000_MC_TBL_SIZE; i++) + mta_size = E1000_MC_TBL_SIZE; + for(i = 0; i < mta_size; i++) E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); /* Set the PCI priority bit correctly in the CTRL register. This * determines if the adapter gives priority to receives, or if it - * gives equal priority to transmits and receives. + * gives equal priority to transmits and receives. Valid only on + * 82542 and 82543 silicon. */ - if(hw->dma_fairness) { + if(hw->dma_fairness && hw->mac_type <= e1000_82543) { ctrl = E1000_READ_REG(hw, CTRL); E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR); } @@ -598,9 +672,21 @@ e1000_init_hw(struct e1000_hw *hw) if(hw->mac_type > e1000_82544) { ctrl = E1000_READ_REG(hw, TXDCTL); ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; + switch (hw->mac_type) { + default: + break; + case e1000_82573: + ctrl |= E1000_TXDCTL_COUNT_DESC; + break; + } E1000_WRITE_REG(hw, TXDCTL, ctrl); } + if (hw->mac_type == e1000_82573) { + e1000_enable_tx_pkt_filtering(hw); + } + + /* Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there @@ -679,7 +765,7 @@ e1000_setup_link(struct e1000_hw *hw) * control setting, then the variable hw->fc will * be initialized based on a value in the EEPROM. */ - if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 0) { + if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data)) { DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } @@ -736,6 +822,7 @@ e1000_setup_link(struct e1000_hw *hw) E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW); E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH); E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE); + E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time); /* Set the flow control receive threshold registers. Normally, @@ -906,20 +993,18 @@ e1000_setup_fiber_serdes_link(struct e1000_hw *hw) } /****************************************************************************** -* Detects which PHY is present and the speed and duplex +* Make sure we have a valid PHY and change PHY mode before link setup. * * hw - Struct containing variables accessed by shared code ******************************************************************************/ static int32_t -e1000_setup_copper_link(struct e1000_hw *hw) +e1000_copper_link_preconfig(struct e1000_hw *hw) { uint32_t ctrl; - uint32_t led_ctrl; int32_t ret_val; - uint16_t i; uint16_t phy_data; - DEBUGFUNC("e1000_setup_copper_link"); + DEBUGFUNC("e1000_copper_link_preconfig"); ctrl = E1000_READ_REG(hw, CTRL); /* With 82543, we need to force speed and duplex on the MAC equal to what @@ -933,7 +1018,9 @@ e1000_setup_copper_link(struct e1000_hw *hw) } else { ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | E1000_CTRL_SLU); E1000_WRITE_REG(hw, CTRL, ctrl); - e1000_phy_hw_reset(hw); + ret_val = e1000_phy_hw_reset(hw); + if(ret_val) + return ret_val; } /* Make sure we have a valid PHY */ @@ -961,354 +1048,452 @@ e1000_setup_copper_link(struct e1000_hw *hw) hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) hw->phy_reset_disable = FALSE; - if(!hw->phy_reset_disable) { - if (hw->phy_type == e1000_phy_igp) { - - ret_val = e1000_phy_reset(hw); - if(ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } - - /* Wait 10ms for MAC to configure PHY from eeprom settings */ - msec_delay(15); + return E1000_SUCCESS; +} - /* Configure activity LED after PHY reset */ - led_ctrl = E1000_READ_REG(hw, LEDCTL); - led_ctrl &= IGP_ACTIVITY_LED_MASK; - led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); - E1000_WRITE_REG(hw, LEDCTL, led_ctrl); - /* disable lplu d3 during driver init */ - ret_val = e1000_set_d3_lplu_state(hw, FALSE); - if(ret_val) { - DEBUGOUT("Error Disabling LPLU D3\n"); - return ret_val; - } +/******************************************************************** +* Copper link setup for e1000_phy_igp series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +e1000_copper_link_igp_setup(struct e1000_hw *hw) +{ + uint32_t led_ctrl; + int32_t ret_val; + uint16_t phy_data; - /* Configure mdi-mdix settings */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, - &phy_data); - if(ret_val) - return ret_val; + DEBUGFUNC("e1000_copper_link_igp_setup"); - if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { - hw->dsp_config_state = e1000_dsp_config_disabled; - /* Force MDI for earlier revs of the IGP PHY */ - phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | - IGP01E1000_PSCR_FORCE_MDI_MDIX); - hw->mdix = 1; + if (hw->phy_reset_disable) + return E1000_SUCCESS; + + ret_val = e1000_phy_reset(hw); + if (ret_val) { + DEBUGOUT("Error Resetting the PHY\n"); + return ret_val; + } - } else { - hw->dsp_config_state = e1000_dsp_config_enabled; - phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; - - switch (hw->mdix) { - case 1: - phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; - break; - case 2: - phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; - break; - case 0: - default: - phy_data |= IGP01E1000_PSCR_AUTO_MDIX; - break; - } - } - ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, - phy_data); - if(ret_val) - return ret_val; + /* Wait 10ms for MAC to configure PHY from eeprom settings */ + msec_delay(15); - /* set auto-master slave resolution settings */ - if(hw->autoneg) { - e1000_ms_type phy_ms_setting = hw->master_slave; + /* Configure activity LED after PHY reset */ + led_ctrl = E1000_READ_REG(hw, LEDCTL); + led_ctrl &= IGP_ACTIVITY_LED_MASK; + led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); + E1000_WRITE_REG(hw, LEDCTL, led_ctrl); - if(hw->ffe_config_state == e1000_ffe_config_active) - hw->ffe_config_state = e1000_ffe_config_enabled; + /* disable lplu d3 during driver init */ + ret_val = e1000_set_d3_lplu_state(hw, FALSE); + if (ret_val) { + DEBUGOUT("Error Disabling LPLU D3\n"); + return ret_val; + } - if(hw->dsp_config_state == e1000_dsp_config_activated) - hw->dsp_config_state = e1000_dsp_config_enabled; + /* disable lplu d0 during driver init */ + ret_val = e1000_set_d0_lplu_state(hw, FALSE); + if (ret_val) { + DEBUGOUT("Error Disabling LPLU D0\n"); + return ret_val; + } + /* Configure mdi-mdix settings */ + ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); + if (ret_val) + return ret_val; - /* when autonegotiation advertisment is only 1000Mbps then we - * should disable SmartSpeed and enable Auto MasterSlave - * resolution as hardware default. */ - if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { - /* Disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, - &phy_data); - if(ret_val) - return ret_val; - phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - phy_data); - if(ret_val) - return ret_val; - /* Set auto Master/Slave resolution process */ - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if(ret_val) - return ret_val; - phy_data &= ~CR_1000T_MS_ENABLE; - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if(ret_val) - return ret_val; - } + if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { + hw->dsp_config_state = e1000_dsp_config_disabled; + /* Force MDI for earlier revs of the IGP PHY */ + phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX | IGP01E1000_PSCR_FORCE_MDI_MDIX); + hw->mdix = 1; - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); - if(ret_val) - return ret_val; + } else { + hw->dsp_config_state = e1000_dsp_config_enabled; + phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; - /* load defaults for future use */ - hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? - ((phy_data & CR_1000T_MS_VALUE) ? - e1000_ms_force_master : - e1000_ms_force_slave) : - e1000_ms_auto; - - switch (phy_ms_setting) { - case e1000_ms_force_master: - phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); - break; - case e1000_ms_force_slave: - phy_data |= CR_1000T_MS_ENABLE; - phy_data &= ~(CR_1000T_MS_VALUE); - break; - case e1000_ms_auto: - phy_data &= ~CR_1000T_MS_ENABLE; - default: - break; - } - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); - if(ret_val) - return ret_val; - } - } else { - /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - &phy_data); - if(ret_val) - return ret_val; + switch (hw->mdix) { + case 1: + phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; + break; + case 2: + phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX; + break; + case 0: + default: + phy_data |= IGP01E1000_PSCR_AUTO_MDIX; + break; + } + } + ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); + if(ret_val) + return ret_val; - phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; + /* set auto-master slave resolution settings */ + if(hw->autoneg) { + e1000_ms_type phy_ms_setting = hw->master_slave; - /* Options: - * MDI/MDI-X = 0 (default) - * 0 - Auto for all speeds - * 1 - MDI mode - * 2 - MDI-X mode - * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) - */ - phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; + if(hw->ffe_config_state == e1000_ffe_config_active) + hw->ffe_config_state = e1000_ffe_config_enabled; - switch (hw->mdix) { - case 1: - phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; - break; - case 2: - phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; - break; - case 3: - phy_data |= M88E1000_PSCR_AUTO_X_1000T; - break; - case 0: - default: - phy_data |= M88E1000_PSCR_AUTO_X_MODE; - break; - } + if(hw->dsp_config_state == e1000_dsp_config_activated) + hw->dsp_config_state = e1000_dsp_config_enabled; - /* Options: - * disable_polarity_correction = 0 (default) - * Automatic Correction for Reversed Cable Polarity - * 0 - Disabled - * 1 - Enabled - */ - phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; - if(hw->disable_polarity_correction == 1) - phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, - phy_data); + /* when autonegotiation advertisment is only 1000Mbps then we + * should disable SmartSpeed and enable Auto MasterSlave + * resolution as hardware default. */ + if(hw->autoneg_advertised == ADVERTISE_1000_FULL) { + /* Disable SmartSpeed */ + ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); if(ret_val) return ret_val; - - /* Force TX_CLK in the Extended PHY Specific Control Register - * to 25MHz clock. - */ - ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - &phy_data); + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + ret_val = e1000_write_phy_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + phy_data); if(ret_val) return ret_val; + /* Set auto Master/Slave resolution process */ + ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); + if(ret_val) + return ret_val; + phy_data &= ~CR_1000T_MS_ENABLE; + ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); + if(ret_val) + return ret_val; + } - phy_data |= M88E1000_EPSCR_TX_CLK_25; + ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &phy_data); + if(ret_val) + return ret_val; - if (hw->phy_revision < M88E1011_I_REV_4) { - /* Configure Master and Slave downshift values */ - phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | - M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); - phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | - M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); - ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, - phy_data); - if(ret_val) - return ret_val; - } + /* load defaults for future use */ + hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ? + ((phy_data & CR_1000T_MS_VALUE) ? + e1000_ms_force_master : + e1000_ms_force_slave) : + e1000_ms_auto; - /* SW Reset the PHY so all changes take effect */ - ret_val = e1000_phy_reset(hw); - if(ret_val) { - DEBUGOUT("Error Resetting the PHY\n"); - return ret_val; - } + switch (phy_ms_setting) { + case e1000_ms_force_master: + phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE); + break; + case e1000_ms_force_slave: + phy_data |= CR_1000T_MS_ENABLE; + phy_data &= ~(CR_1000T_MS_VALUE); + break; + case e1000_ms_auto: + phy_data &= ~CR_1000T_MS_ENABLE; + default: + break; + } + ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, phy_data); + if(ret_val) + return ret_val; } - /* Options: - * autoneg = 1 (default) - * PHY will advertise value(s) parsed from - * autoneg_advertised and fc - * autoneg = 0 - * PHY will be set to 10H, 10F, 100H, or 100F - * depending on value parsed from forced_speed_duplex. - */ + return E1000_SUCCESS; +} - /* Is autoneg enabled? This is enabled by default or by software - * override. If so, call e1000_phy_setup_autoneg routine to parse the - * autoneg_advertised and fc options. If autoneg is NOT enabled, then - * the user should have provided a speed/duplex override. If so, then - * call e1000_phy_force_speed_duplex to parse and set this up. - */ - if(hw->autoneg) { - /* Perform some bounds checking on the hw->autoneg_advertised - * parameter. If this variable is zero, then set it to the default. - */ - hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; - /* If autoneg_advertised is zero, we assume it was not defaulted - * by the calling code so we set to advertise full capability. - */ - if(hw->autoneg_advertised == 0) - hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; +/******************************************************************** +* Copper link setup for e1000_phy_m88 series. +* +* hw - Struct containing variables accessed by shared code +*********************************************************************/ +static int32_t +e1000_copper_link_mgp_setup(struct e1000_hw *hw) +{ + int32_t ret_val; + uint16_t phy_data; - DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); - ret_val = e1000_phy_setup_autoneg(hw); - if(ret_val) { - DEBUGOUT("Error Setting up Auto-Negotiation\n"); - return ret_val; - } - DEBUGOUT("Restarting Auto-Neg\n"); + DEBUGFUNC("e1000_copper_link_mgp_setup"); - /* Restart auto-negotiation by setting the Auto Neg Enable bit and - * the Auto Neg Restart bit in the PHY control register. - */ - ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); - if(ret_val) - return ret_val; + if(hw->phy_reset_disable) + return E1000_SUCCESS; + + /* Enable CRS on TX. This must be set for half-duplex operation. */ + ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + if(ret_val) + return ret_val; - phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); - ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); - if(ret_val) - return ret_val; + phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - /* Does the user want to wait for Auto-Neg to complete here, or - * check at a later time (for example, callback routine). - */ - if(hw->wait_autoneg_complete) { - ret_val = e1000_wait_autoneg(hw); - if(ret_val) { - DEBUGOUT("Error while waiting for autoneg to complete\n"); - return ret_val; - } - } - hw->get_link_status = TRUE; - } else { - DEBUGOUT("Forcing speed and duplex\n"); - ret_val = e1000_phy_force_speed_duplex(hw); - if(ret_val) { - DEBUGOUT("Error Forcing Speed and Duplex\n"); - return ret_val; - } - } - } /* !hw->phy_reset_disable */ + /* Options: + * MDI/MDI-X = 0 (default) + * 0 - Auto for all speeds + * 1 - MDI mode + * 2 - MDI-X mode + * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) + */ + phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; - /* Check link status. Wait up to 100 microseconds for link to become - * valid. + switch (hw->mdix) { + case 1: + phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE; + break; + case 2: + phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE; + break; + case 3: + phy_data |= M88E1000_PSCR_AUTO_X_1000T; + break; + case 0: + default: + phy_data |= M88E1000_PSCR_AUTO_X_MODE; + break; + } + + /* Options: + * disable_polarity_correction = 0 (default) + * Automatic Correction for Reversed Cable Polarity + * 0 - Disabled + * 1 - Enabled */ - for(i = 0; i < 10; i++) { - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); + phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL; + if(hw->disable_polarity_correction == 1) + phy_data |= M88E1000_PSCR_POLARITY_REVERSAL; + ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if(ret_val) return ret_val; - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); + + /* Force TX_CLK in the Extended PHY Specific Control Register + * to 25MHz clock. + */ + ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); + if(ret_val) + return ret_val; + + phy_data |= M88E1000_EPSCR_TX_CLK_25; + + if (hw->phy_revision < M88E1011_I_REV_4) { + /* Configure Master and Slave downshift values */ + phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK | + M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK); + phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | + M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); + ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); if(ret_val) return ret_val; + } - if(phy_data & MII_SR_LINK_STATUS) { - /* We have link, so we need to finish the config process: - * 1) Set up the MAC to the current PHY speed/duplex - * if we are on 82543. If we - * are on newer silicon, we only need to configure - * collision distance in the Transmit Control Register. - * 2) Set up flow control on the MAC to that established with - * the link partner. - */ - if(hw->mac_type >= e1000_82544) { - e1000_config_collision_dist(hw); - } else { - ret_val = e1000_config_mac_to_phy(hw); - if(ret_val) { - DEBUGOUT("Error configuring MAC to PHY settings\n"); - return ret_val; - } - } - ret_val = e1000_config_fc_after_link_up(hw); - if(ret_val) { - DEBUGOUT("Error Configuring Flow Control\n"); - return ret_val; - } - DEBUGOUT("Valid link established!!!\n"); - - if(hw->phy_type == e1000_phy_igp) { - ret_val = e1000_config_dsp_after_link_change(hw, TRUE); - if(ret_val) { - DEBUGOUT("Error Configuring DSP after link up\n"); - return ret_val; - } - } - DEBUGOUT("Valid link established!!!\n"); - return E1000_SUCCESS; - } - udelay(10); + /* SW Reset the PHY so all changes take effect */ + ret_val = e1000_phy_reset(hw); + if(ret_val) { + DEBUGOUT("Error Resetting the PHY\n"); + return ret_val; } - DEBUGOUT("Unable to establish link!!!\n"); - return E1000_SUCCESS; + return E1000_SUCCESS; } -/****************************************************************************** -* Configures PHY autoneg and flow control advertisement settings +/******************************************************************** +* Setup auto-negotiation and flow control advertisements, +* and then perform auto-negotiation. * * hw - Struct containing variables accessed by shared code -******************************************************************************/ -int32_t -e1000_phy_setup_autoneg(struct e1000_hw *hw) +*********************************************************************/ +static int32_t +e1000_copper_link_autoneg(struct e1000_hw *hw) { int32_t ret_val; - uint16_t mii_autoneg_adv_reg; - uint16_t mii_1000t_ctrl_reg; + uint16_t phy_data; - DEBUGFUNC("e1000_phy_setup_autoneg"); + DEBUGFUNC("e1000_copper_link_autoneg"); - /* Read the MII Auto-Neg Advertisement Register (Address 4). */ - ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); + /* Perform some bounds checking on the hw->autoneg_advertised + * parameter. If this variable is zero, then set it to the default. + */ + hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT; + + /* If autoneg_advertised is zero, we assume it was not defaulted + * by the calling code so we set to advertise full capability. + */ + if(hw->autoneg_advertised == 0) + hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT; + + DEBUGOUT("Reconfiguring auto-neg advertisement params\n"); + ret_val = e1000_phy_setup_autoneg(hw); + if(ret_val) { + DEBUGOUT("Error Setting up Auto-Negotiation\n"); + return ret_val; + } + DEBUGOUT("Restarting Auto-Neg\n"); + + /* Restart auto-negotiation by setting the Auto Neg Enable bit and + * the Auto Neg Restart bit in the PHY control register. + */ + ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); if(ret_val) return ret_val; - /* Read the MII 1000Base-T Control Register (Address 9). */ - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); + phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); + ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data); if(ret_val) return ret_val; - /* Need to parse both autoneg_advertised and fc and set up - * the appropriate PHY registers. First we will parse for + /* Does the user want to wait for Auto-Neg to complete here, or + * check at a later time (for example, callback routine). + */ + if(hw->wait_autoneg_complete) { + ret_val = e1000_wait_autoneg(hw); + if(ret_val) { + DEBUGOUT("Error while waiting for autoneg to complete\n"); + return ret_val; + } + } + + hw->get_link_status = TRUE; + + return E1000_SUCCESS; +} + + +/****************************************************************************** +* Config the MAC and the PHY after link is up. +* 1) Set up the MAC to the current PHY speed/duplex +* if we are on 82543. If we +* are on newer silicon, we only need to configure +* collision distance in the Transmit Control Register. +* 2) Set up flow control on the MAC to that established with +* the link partner. +* 3) Config DSP to improve Gigabit link quality for some PHY revisions. +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int32_t +e1000_copper_link_postconfig(struct e1000_hw *hw) +{ + int32_t ret_val; + DEBUGFUNC("e1000_copper_link_postconfig"); + + if(hw->mac_type >= e1000_82544) { + e1000_config_collision_dist(hw); + } else { + ret_val = e1000_config_mac_to_phy(hw); + if(ret_val) { + DEBUGOUT("Error configuring MAC to PHY settings\n"); + return ret_val; + } + } + ret_val = e1000_config_fc_after_link_up(hw); + if(ret_val) { + DEBUGOUT("Error Configuring Flow Control\n"); + return ret_val; + } + + /* Config DSP to improve Giga link quality */ + if(hw->phy_type == e1000_phy_igp) { + ret_val = e1000_config_dsp_after_link_change(hw, TRUE); + if(ret_val) { + DEBUGOUT("Error Configuring DSP after link up\n"); + return ret_val; + } + } + + return E1000_SUCCESS; +} + +/****************************************************************************** +* Detects which PHY is present and setup the speed and duplex +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +static int32_t +e1000_setup_copper_link(struct e1000_hw *hw) +{ + int32_t ret_val; + uint16_t i; + uint16_t phy_data; + + DEBUGFUNC("e1000_setup_copper_link"); + + /* Check if it is a valid PHY and set PHY mode if necessary. */ + ret_val = e1000_copper_link_preconfig(hw); + if(ret_val) + return ret_val; + + if (hw->phy_type == e1000_phy_igp || + hw->phy_type == e1000_phy_igp_2) { + ret_val = e1000_copper_link_igp_setup(hw); + if(ret_val) + return ret_val; + } else if (hw->phy_type == e1000_phy_m88) { + ret_val = e1000_copper_link_mgp_setup(hw); + if(ret_val) + return ret_val; + } + + if(hw->autoneg) { + /* Setup autoneg and flow control advertisement + * and perform autonegotiation */ + ret_val = e1000_copper_link_autoneg(hw); + if(ret_val) + return ret_val; + } else { + /* PHY will be set to 10H, 10F, 100H,or 100F + * depending on value from forced_speed_duplex. */ + DEBUGOUT("Forcing speed and duplex\n"); + ret_val = e1000_phy_force_speed_duplex(hw); + if(ret_val) { + DEBUGOUT("Error Forcing Speed and Duplex\n"); + return ret_val; + } + } + + /* Check link status. Wait up to 100 microseconds for link to become + * valid. + */ + for(i = 0; i < 10; i++) { + ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); + if(ret_val) + return ret_val; + ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data); + if(ret_val) + return ret_val; + + if(phy_data & MII_SR_LINK_STATUS) { + /* Config the MAC and PHY after link is up */ + ret_val = e1000_copper_link_postconfig(hw); + if(ret_val) + return ret_val; + + DEBUGOUT("Valid link established!!!\n"); + return E1000_SUCCESS; + } + udelay(10); + } + + DEBUGOUT("Unable to establish link!!!\n"); + return E1000_SUCCESS; +} + +/****************************************************************************** +* Configures PHY autoneg and flow control advertisement settings +* +* hw - Struct containing variables accessed by shared code +******************************************************************************/ +int32_t +e1000_phy_setup_autoneg(struct e1000_hw *hw) +{ + int32_t ret_val; + uint16_t mii_autoneg_adv_reg; + uint16_t mii_1000t_ctrl_reg; + + DEBUGFUNC("e1000_phy_setup_autoneg"); + + /* Read the MII Auto-Neg Advertisement Register (Address 4). */ + ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); + if(ret_val) + return ret_val; + + /* Read the MII 1000Base-T Control Register (Address 9). */ + ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); + if(ret_val) + return ret_val; + + /* Need to parse both autoneg_advertised and fc and set up + * the appropriate PHY registers. First we will parse for * autoneg_advertised software override. Since we can advertise * a plethora of combinations, we need to check each bit * individually. @@ -1417,7 +1602,7 @@ e1000_phy_setup_autoneg(struct e1000_hw *hw) DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); + ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); if(ret_val) return ret_val; @@ -1678,6 +1863,11 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) DEBUGFUNC("e1000_config_mac_to_phy"); + /* 82544 or newer MAC, Auto Speed Detection takes care of + * MAC speed/duplex configuration.*/ + if (hw->mac_type >= e1000_82544) + return E1000_SUCCESS; + /* Read the Device Control Register and set the bits to Force Speed * and Duplex. */ @@ -1688,45 +1878,25 @@ e1000_config_mac_to_phy(struct e1000_hw *hw) /* Set up duplex in the Device Control and Transmit Control * registers depending on negotiated values. */ - if (hw->phy_type == e1000_phy_igp) { - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, - &phy_data); - if(ret_val) - return ret_val; - - if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= E1000_CTRL_FD; - else ctrl &= ~E1000_CTRL_FD; - - e1000_config_collision_dist(hw); + ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + if(ret_val) + return ret_val; - /* Set up speed in the Device Control register depending on - * negotiated values. - */ - if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == - IGP01E1000_PSSR_SPEED_1000MBPS) - ctrl |= E1000_CTRL_SPD_1000; - else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) == - IGP01E1000_PSSR_SPEED_100MBPS) - ctrl |= E1000_CTRL_SPD_100; - } else { - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, - &phy_data); - if(ret_val) - return ret_val; + if(phy_data & M88E1000_PSSR_DPLX) + ctrl |= E1000_CTRL_FD; + else + ctrl &= ~E1000_CTRL_FD; - if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD; - else ctrl &= ~E1000_CTRL_FD; + e1000_config_collision_dist(hw); - e1000_config_collision_dist(hw); + /* Set up speed in the Device Control register depending on + * negotiated values. + */ + if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) + ctrl |= E1000_CTRL_SPD_1000; + else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) + ctrl |= E1000_CTRL_SPD_100; - /* Set up speed in the Device Control register depending on - * negotiated values. - */ - if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) - ctrl |= E1000_CTRL_SPD_1000; - else if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_100MBS) - ctrl |= E1000_CTRL_SPD_100; - } /* Write the configured values back to the Device Control Reg. */ E1000_WRITE_REG(hw, CTRL, ctrl); return E1000_SUCCESS; @@ -2494,8 +2664,8 @@ e1000_read_phy_reg(struct e1000_hw *hw, DEBUGFUNC("e1000_read_phy_reg"); - - if(hw->phy_type == e1000_phy_igp && + if((hw->phy_type == e1000_phy_igp || + hw->phy_type == e1000_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); @@ -2600,8 +2770,8 @@ e1000_write_phy_reg(struct e1000_hw *hw, DEBUGFUNC("e1000_write_phy_reg"); - - if(hw->phy_type == e1000_phy_igp && + if((hw->phy_type == e1000_phy_igp || + hw->phy_type == e1000_phy_igp_2) && (reg_addr > MAX_PHY_MULTI_PAGE_REG)) { ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT, (uint16_t)reg_addr); @@ -2679,19 +2849,27 @@ e1000_write_phy_reg_ex(struct e1000_hw *hw, return E1000_SUCCESS; } + /****************************************************************************** * Returns the PHY to the power-on reset state * * hw - Struct containing variables accessed by shared code ******************************************************************************/ -void +int32_t e1000_phy_hw_reset(struct e1000_hw *hw) { uint32_t ctrl, ctrl_ext; uint32_t led_ctrl; + int32_t ret_val; DEBUGFUNC("e1000_phy_hw_reset"); + /* In the case of the phy reset being blocked, it's not an error, we + * simply return success without performing the reset. */ + ret_val = e1000_check_phy_reset_block(hw); + if (ret_val) + return E1000_SUCCESS; + DEBUGOUT("Resetting Phy...\n"); if(hw->mac_type > e1000_82543) { @@ -2727,6 +2905,11 @@ e1000_phy_hw_reset(struct e1000_hw *hw) led_ctrl |= (IGP_ACTIVITY_LED_ENABLE | IGP_LED3_MODE); E1000_WRITE_REG(hw, LEDCTL, led_ctrl); } + + /* Wait for FW to finish PHY configuration. */ + ret_val = e1000_get_phy_cfg_done(hw); + + return ret_val; } /****************************************************************************** @@ -2744,7 +2927,19 @@ e1000_phy_reset(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_reset"); - if(hw->mac_type != e1000_82541_rev_2) { + /* In the case of the phy reset being blocked, it's not an error, we + * simply return success without performing the reset. */ + ret_val = e1000_check_phy_reset_block(hw); + if (ret_val) + return E1000_SUCCESS; + + switch (hw->mac_type) { + case e1000_82541_rev_2: + ret_val = e1000_phy_hw_reset(hw); + if(ret_val) + return ret_val; + break; + default: ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data); if(ret_val) return ret_val; @@ -2755,9 +2950,10 @@ e1000_phy_reset(struct e1000_hw *hw) return ret_val; udelay(1); - } else e1000_phy_hw_reset(hw); + break; + } - if(hw->phy_type == e1000_phy_igp) + if(hw->phy_type == e1000_phy_igp || hw->phy_type == e1000_phy_igp_2) e1000_phy_init_script(hw); return E1000_SUCCESS; @@ -2811,6 +3007,9 @@ e1000_detect_gig_phy(struct e1000_hw *hw) case e1000_82547_rev_2: if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE; break; + case e1000_82573: + if(hw->phy_id == M88E1111_I_PHY_ID) match = TRUE; + break; default: DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type); return -E1000_ERR_CONFIG; @@ -2866,7 +3065,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, /* The downshift status is checked only once, after link is established, * and it stored in the hw->speed_downgraded parameter. */ - phy_info->downshift = hw->speed_downgraded; + phy_info->downshift = (e1000_downshift)hw->speed_downgraded; /* IGP01E1000 does not need to support it. */ phy_info->extended_10bt_distance = e1000_10bt_ext_dist_enable_normal; @@ -2905,7 +3104,7 @@ e1000_phy_igp_get_info(struct e1000_hw *hw, if(ret_val) return ret_val; - /* transalte to old method */ + /* Translate to old method */ average = (max_length + min_length) / 2; if(average <= e1000_igp_cable_length_50) @@ -2940,7 +3139,7 @@ e1000_phy_m88_get_info(struct e1000_hw *hw, /* The downshift status is checked only once, after link is established, * and it stored in the hw->speed_downgraded parameter. */ - phy_info->downshift = hw->speed_downgraded; + phy_info->downshift = (e1000_downshift)hw->speed_downgraded; ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if(ret_val) @@ -3029,7 +3228,8 @@ e1000_phy_get_info(struct e1000_hw *hw, return -E1000_ERR_CONFIG; } - if(hw->phy_type == e1000_phy_igp) + if(hw->phy_type == e1000_phy_igp || + hw->phy_type == e1000_phy_igp_2) return e1000_phy_igp_get_info(hw, phy_info); else return e1000_phy_m88_get_info(hw, phy_info); @@ -3055,11 +3255,12 @@ e1000_validate_mdi_setting(struct e1000_hw *hw) * * hw - Struct containing variables accessed by shared code *****************************************************************************/ -void +int32_t e1000_init_eeprom_params(struct e1000_hw *hw) { struct e1000_eeprom_info *eeprom = &hw->eeprom; uint32_t eecd = E1000_READ_REG(hw, EECD); + int32_t ret_val = E1000_SUCCESS; uint16_t eeprom_size; DEBUGFUNC("e1000_init_eeprom_params"); @@ -3074,6 +3275,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->opcode_bits = 3; eeprom->address_bits = 6; eeprom->delay_usec = 50; + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; break; case e1000_82540: case e1000_82545: @@ -3090,6 +3293,8 @@ e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->word_size = 64; eeprom->address_bits = 6; } + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; break; case e1000_82541: case e1000_82541_rev_2: @@ -3118,42 +3323,60 @@ e1000_init_eeprom_params(struct e1000_hw *hw) eeprom->address_bits = 6; } } + eeprom->use_eerd = FALSE; + eeprom->use_eewr = FALSE; + break; + case e1000_82573: + eeprom->type = e1000_eeprom_spi; + eeprom->opcode_bits = 8; + eeprom->delay_usec = 1; + if (eecd & E1000_EECD_ADDR_BITS) { + eeprom->page_size = 32; + eeprom->address_bits = 16; + } else { + eeprom->page_size = 8; + eeprom->address_bits = 8; + } + eeprom->use_eerd = TRUE; + eeprom->use_eewr = TRUE; + if(e1000_is_onboard_nvm_eeprom(hw) == FALSE) { + eeprom->type = e1000_eeprom_flash; + eeprom->word_size = 2048; + + /* Ensure that the Autonomous FLASH update bit is cleared due to + * Flash update issue on parts which use a FLASH for NVM. */ + eecd &= ~E1000_EECD_AUPDEN; + E1000_WRITE_REG(hw, EECD, eecd); + } break; default: break; } if (eeprom->type == e1000_eeprom_spi) { - eeprom->word_size = 64; - if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) { - eeprom_size &= EEPROM_SIZE_MASK; - - switch (eeprom_size) { - case EEPROM_SIZE_16KB: - eeprom->word_size = 8192; - break; - case EEPROM_SIZE_8KB: - eeprom->word_size = 4096; - break; - case EEPROM_SIZE_4KB: - eeprom->word_size = 2048; - break; - case EEPROM_SIZE_2KB: - eeprom->word_size = 1024; - break; - case EEPROM_SIZE_1KB: - eeprom->word_size = 512; - break; - case EEPROM_SIZE_512B: - eeprom->word_size = 256; - break; - case EEPROM_SIZE_128B: - default: - eeprom->word_size = 64; - break; - } + /* eeprom_size will be an enum [0..8] that maps to eeprom sizes 128B to + * 32KB (incremented by powers of 2). + */ + if(hw->mac_type <= e1000_82547_rev_2) { + /* Set to default value for initial eeprom read. */ + eeprom->word_size = 64; + ret_val = e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size); + if(ret_val) + return ret_val; + eeprom_size = (eeprom_size & EEPROM_SIZE_MASK) >> EEPROM_SIZE_SHIFT; + /* 256B eeprom size was not supported in earlier hardware, so we + * bump eeprom_size up one to ensure that "1" (which maps to 256B) + * is never the result used in the shifting logic below. */ + if(eeprom_size) + eeprom_size++; + } else { + eeprom_size = (uint16_t)((eecd & E1000_EECD_SIZE_EX_MASK) >> + E1000_EECD_SIZE_EX_SHIFT); } + + eeprom->word_size = 1 << (eeprom_size + EEPROM_WORD_SIZE_SHIFT); } + return ret_val; } /****************************************************************************** @@ -3306,8 +3529,12 @@ e1000_acquire_eeprom(struct e1000_hw *hw) DEBUGFUNC("e1000_acquire_eeprom"); + if(e1000_get_hw_eeprom_semaphore(hw)) + return -E1000_ERR_EEPROM; + eecd = E1000_READ_REG(hw, EECD); + if (hw->mac_type != e1000_82573) { /* Request EEPROM Access */ if(hw->mac_type > e1000_82544) { eecd |= E1000_EECD_REQ; @@ -3326,6 +3553,7 @@ e1000_acquire_eeprom(struct e1000_hw *hw) return -E1000_ERR_EEPROM; } } + } /* Setup EEPROM for Read/Write */ @@ -3443,6 +3671,8 @@ e1000_release_eeprom(struct e1000_hw *hw) eecd &= ~E1000_EECD_REQ; E1000_WRITE_REG(hw, EECD, eecd); } + + e1000_put_hw_eeprom_semaphore(hw); } /****************************************************************************** @@ -3504,8 +3734,10 @@ e1000_read_eeprom(struct e1000_hw *hw, { struct e1000_eeprom_info *eeprom = &hw->eeprom; uint32_t i = 0; + int32_t ret_val; DEBUGFUNC("e1000_read_eeprom"); + /* A check for invalid values: offset too large, too many words, and not * enough words. */ @@ -3515,9 +3747,23 @@ e1000_read_eeprom(struct e1000_hw *hw, return -E1000_ERR_EEPROM; } - /* Prepare the EEPROM for reading */ - if(e1000_acquire_eeprom(hw) != E1000_SUCCESS) - return -E1000_ERR_EEPROM; + /* FLASH reads without acquiring the semaphore are safe in 82573-based + * controllers. + */ + if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) || + (hw->mac_type != e1000_82573)) { + /* Prepare the EEPROM for reading */ + if(e1000_acquire_eeprom(hw) != E1000_SUCCESS) + return -E1000_ERR_EEPROM; + } + + if(eeprom->use_eerd == TRUE) { + ret_val = e1000_read_eeprom_eerd(hw, offset, words, data); + if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) || + (hw->mac_type != e1000_82573)) + e1000_release_eeprom(hw); + return ret_val; + } if(eeprom->type == e1000_eeprom_spi) { uint16_t word_in; @@ -3569,65 +3815,212 @@ e1000_read_eeprom(struct e1000_hw *hw, } /****************************************************************************** - * Verifies that the EEPROM has a valid checksum + * Reads a 16 bit word from the EEPROM using the EERD register. * * hw - Struct containing variables accessed by shared code - * - * Reads the first 64 16 bit words of the EEPROM and sums the values read. - * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is - * valid. + * offset - offset of word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read *****************************************************************************/ int32_t -e1000_validate_eeprom_checksum(struct e1000_hw *hw) +e1000_read_eeprom_eerd(struct e1000_hw *hw, + uint16_t offset, + uint16_t words, + uint16_t *data) { - uint16_t checksum = 0; - uint16_t i, eeprom_data; + uint32_t i, eerd = 0; + int32_t error = 0; - DEBUGFUNC("e1000_validate_eeprom_checksum"); + for (i = 0; i < words; i++) { + eerd = ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) + + E1000_EEPROM_RW_REG_START; - for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { - if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; + E1000_WRITE_REG(hw, EERD, eerd); + error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_READ); + + if(error) { + break; } - checksum += eeprom_data; - } - - if(checksum == (uint16_t) EEPROM_SUM) - return E1000_SUCCESS; - else { - DEBUGOUT("EEPROM Checksum Invalid\n"); - return -E1000_ERR_EEPROM; + data[i] = (E1000_READ_REG(hw, EERD) >> E1000_EEPROM_RW_REG_DATA); + } + + return error; } /****************************************************************************** - * Calculates the EEPROM checksum and writes it to the EEPROM + * Writes a 16 bit word from the EEPROM using the EEWR register. * * hw - Struct containing variables accessed by shared code - * - * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. - * Writes the difference to word offset 63 of the EEPROM. + * offset - offset of word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read *****************************************************************************/ int32_t -e1000_update_eeprom_checksum(struct e1000_hw *hw) +e1000_write_eeprom_eewr(struct e1000_hw *hw, + uint16_t offset, + uint16_t words, + uint16_t *data) { - uint16_t checksum = 0; - uint16_t i, eeprom_data; + uint32_t register_value = 0; + uint32_t i = 0; + int32_t error = 0; - DEBUGFUNC("e1000_update_eeprom_checksum"); + for (i = 0; i < words; i++) { + register_value = (data[i] << E1000_EEPROM_RW_REG_DATA) | + ((offset+i) << E1000_EEPROM_RW_ADDR_SHIFT) | + E1000_EEPROM_RW_REG_START; - for(i = 0; i < EEPROM_CHECKSUM_REG; i++) { - if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { - DEBUGOUT("EEPROM Read Error\n"); - return -E1000_ERR_EEPROM; - } - checksum += eeprom_data; - } - checksum = (uint16_t) EEPROM_SUM - checksum; + error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); + if(error) { + break; + } + + E1000_WRITE_REG(hw, EEWR, register_value); + + error = e1000_poll_eerd_eewr_done(hw, E1000_EEPROM_POLL_WRITE); + + if(error) { + break; + } + } + + return error; +} + +/****************************************************************************** + * Polls the status bit (bit 1) of the EERD to determine when the read is done. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +int32_t +e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd) +{ + uint32_t attempts = 100000; + uint32_t i, reg = 0; + int32_t done = E1000_ERR_EEPROM; + + for(i = 0; i < attempts; i++) { + if(eerd == E1000_EEPROM_POLL_READ) + reg = E1000_READ_REG(hw, EERD); + else + reg = E1000_READ_REG(hw, EEWR); + + if(reg & E1000_EEPROM_RW_REG_DONE) { + done = E1000_SUCCESS; + break; + } + udelay(5); + } + + return done; +} + +/*************************************************************************** +* Description: Determines if the onboard NVM is FLASH or EEPROM. +* +* hw - Struct containing variables accessed by shared code +****************************************************************************/ +boolean_t +e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw) +{ + uint32_t eecd = 0; + + if(hw->mac_type == e1000_82573) { + eecd = E1000_READ_REG(hw, EECD); + + /* Isolate bits 15 & 16 */ + eecd = ((eecd >> 15) & 0x03); + + /* If both bits are set, device is Flash type */ + if(eecd == 0x03) { + return FALSE; + } + } + return TRUE; +} + +/****************************************************************************** + * Verifies that the EEPROM has a valid checksum + * + * hw - Struct containing variables accessed by shared code + * + * Reads the first 64 16 bit words of the EEPROM and sums the values read. + * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is + * valid. + *****************************************************************************/ +int32_t +e1000_validate_eeprom_checksum(struct e1000_hw *hw) +{ + uint16_t checksum = 0; + uint16_t i, eeprom_data; + + DEBUGFUNC("e1000_validate_eeprom_checksum"); + + if ((hw->mac_type == e1000_82573) && + (e1000_is_onboard_nvm_eeprom(hw) == FALSE)) { + /* Check bit 4 of word 10h. If it is 0, firmware is done updating + * 10h-12h. Checksum may need to be fixed. */ + e1000_read_eeprom(hw, 0x10, 1, &eeprom_data); + if ((eeprom_data & 0x10) == 0) { + /* Read 0x23 and check bit 15. This bit is a 1 when the checksum + * has already been fixed. If the checksum is still wrong and this + * bit is a 1, we need to return bad checksum. Otherwise, we need + * to set this bit to a 1 and update the checksum. */ + e1000_read_eeprom(hw, 0x23, 1, &eeprom_data); + if ((eeprom_data & 0x8000) == 0) { + eeprom_data |= 0x8000; + e1000_write_eeprom(hw, 0x23, 1, &eeprom_data); + e1000_update_eeprom_checksum(hw); + } + } + } + + for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) { + if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { + DEBUGOUT("EEPROM Read Error\n"); + return -E1000_ERR_EEPROM; + } + checksum += eeprom_data; + } + + if(checksum == (uint16_t) EEPROM_SUM) + return E1000_SUCCESS; + else { + DEBUGOUT("EEPROM Checksum Invalid\n"); + return -E1000_ERR_EEPROM; + } +} + +/****************************************************************************** + * Calculates the EEPROM checksum and writes it to the EEPROM + * + * hw - Struct containing variables accessed by shared code + * + * Sums the first 63 16 bit words of the EEPROM. Subtracts the sum from 0xBABA. + * Writes the difference to word offset 63 of the EEPROM. + *****************************************************************************/ +int32_t +e1000_update_eeprom_checksum(struct e1000_hw *hw) +{ + uint16_t checksum = 0; + uint16_t i, eeprom_data; + + DEBUGFUNC("e1000_update_eeprom_checksum"); + + for(i = 0; i < EEPROM_CHECKSUM_REG; i++) { + if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) { + DEBUGOUT("EEPROM Read Error\n"); + return -E1000_ERR_EEPROM; + } + checksum += eeprom_data; + } + checksum = (uint16_t) EEPROM_SUM - checksum; if(e1000_write_eeprom(hw, EEPROM_CHECKSUM_REG, 1, &checksum) < 0) { DEBUGOUT("EEPROM Write Error\n"); return -E1000_ERR_EEPROM; + } else if (hw->eeprom.type == e1000_eeprom_flash) { + e1000_commit_shadow_ram(hw); } return E1000_SUCCESS; } @@ -3663,6 +4056,10 @@ e1000_write_eeprom(struct e1000_hw *hw, return -E1000_ERR_EEPROM; } + /* 82573 reads only through eerd */ + if(eeprom->use_eewr == TRUE) + return e1000_write_eeprom_eewr(hw, offset, words, data); + /* Prepare the EEPROM for writing */ if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) return -E1000_ERR_EEPROM; @@ -3832,6 +4229,65 @@ e1000_write_eeprom_microwire(struct e1000_hw *hw, return E1000_SUCCESS; } +/****************************************************************************** + * Flushes the cached eeprom to NVM. This is done by saving the modified values + * in the eeprom cache and the non modified values in the currently active bank + * to the new bank. + * + * hw - Struct containing variables accessed by shared code + * offset - offset of word in the EEPROM to read + * data - word read from the EEPROM + * words - number of words to read + *****************************************************************************/ +int32_t +e1000_commit_shadow_ram(struct e1000_hw *hw) +{ + uint32_t attempts = 100000; + uint32_t eecd = 0; + uint32_t flop = 0; + uint32_t i = 0; + int32_t error = E1000_SUCCESS; + + /* The flop register will be used to determine if flash type is STM */ + flop = E1000_READ_REG(hw, FLOP); + + if (hw->mac_type == e1000_82573) { + for (i=0; i < attempts; i++) { + eecd = E1000_READ_REG(hw, EECD); + if ((eecd & E1000_EECD_FLUPD) == 0) { + break; + } + udelay(5); + } + + if (i == attempts) { + return -E1000_ERR_EEPROM; + } + + /* If STM opcode located in bits 15:8 of flop, reset firmware */ + if ((flop & 0xFF00) == E1000_STM_OPCODE) { + E1000_WRITE_REG(hw, HICR, E1000_HICR_FW_RESET); + } + + /* Perform the flash update */ + E1000_WRITE_REG(hw, EECD, eecd | E1000_EECD_FLUPD); + + for (i=0; i < attempts; i++) { + eecd = E1000_READ_REG(hw, EECD); + if ((eecd & E1000_EECD_FLUPD) == 0) { + break; + } + udelay(5); + } + + if (i == attempts) { + return -E1000_ERR_EEPROM; + } + } + + return error; +} + /****************************************************************************** * Reads the adapter's part number from the EEPROM * @@ -3911,6 +4367,7 @@ void e1000_init_rx_addrs(struct e1000_hw *hw) { uint32_t i; + uint32_t rar_num; DEBUGFUNC("e1000_init_rx_addrs"); @@ -3919,9 +4376,10 @@ e1000_init_rx_addrs(struct e1000_hw *hw) e1000_rar_set(hw, hw->mac_addr, 0); + rar_num = E1000_RAR_ENTRIES; /* Zero out the other 15 receive addresses. */ DEBUGOUT("Clearing RAR[1-15]\n"); - for(i = 1; i < E1000_RAR_ENTRIES; i++) { + for(i = 1; i < rar_num; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); } @@ -3950,7 +4408,9 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, { uint32_t hash_value; uint32_t i; - + uint32_t num_rar_entry; + uint32_t num_mta_entry; + DEBUGFUNC("e1000_mc_addr_list_update"); /* Set the new number of MC addresses that we are being requested to use. */ @@ -3958,14 +4418,16 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, /* Clear RAR[1-15] */ DEBUGOUT(" Clearing RAR[1-15]\n"); - for(i = rar_used_count; i < E1000_RAR_ENTRIES; i++) { + num_rar_entry = E1000_RAR_ENTRIES; + for(i = rar_used_count; i < num_rar_entry; i++) { E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0); E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0); } /* Clear the MTA */ DEBUGOUT(" Clearing MTA\n"); - for(i = 0; i < E1000_NUM_MTA_REGISTERS; i++) { + num_mta_entry = E1000_NUM_MTA_REGISTERS; + for(i = 0; i < num_mta_entry; i++) { E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); } @@ -3989,7 +4451,7 @@ e1000_mc_addr_list_update(struct e1000_hw *hw, /* Place this multicast address in the RAR if there is room, * * else put it in the MTA */ - if(rar_used_count < E1000_RAR_ENTRIES) { + if (rar_used_count < num_rar_entry) { e1000_rar_set(hw, mc_addr_list + (i * (ETH_LENGTH_OF_ADDRESS + pad)), rar_used_count); @@ -4040,6 +4502,7 @@ e1000_hash_mc_addr(struct e1000_hw *hw, } hash_value &= 0xFFF; + return hash_value; } @@ -4144,12 +4607,33 @@ void e1000_clear_vfta(struct e1000_hw *hw) { uint32_t offset; - - for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) - E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0); + uint32_t vfta_value = 0; + uint32_t vfta_offset = 0; + uint32_t vfta_bit_in_reg = 0; + + if (hw->mac_type == e1000_82573) { + if (hw->mng_cookie.vlan_id != 0) { + /* The VFTA is a 4096b bit-field, each identifying a single VLAN + * ID. The following operations determine which 32b entry + * (i.e. offset) into the array we want to set the VLAN ID + * (i.e. bit) of the manageability unit. */ + vfta_offset = (hw->mng_cookie.vlan_id >> + E1000_VFTA_ENTRY_SHIFT) & + E1000_VFTA_ENTRY_MASK; + vfta_bit_in_reg = 1 << (hw->mng_cookie.vlan_id & + E1000_VFTA_ENTRY_BIT_SHIFT_MASK); + } + } + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + /* If the offset we want to clear is the same offset of the + * manageability VLAN ID, then clear all bits except that of the + * manageability unit */ + vfta_value = (offset == vfta_offset) ? vfta_bit_in_reg : 0; + E1000_WRITE_REG_ARRAY(hw, VFTA, offset, vfta_value); + } } -static int32_t +int32_t e1000_id_led_init(struct e1000_hw * hw) { uint32_t ledctl; @@ -4480,6 +4964,19 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw) temp = E1000_READ_REG(hw, MGTPRC); temp = E1000_READ_REG(hw, MGTPDC); temp = E1000_READ_REG(hw, MGTPTC); + + if(hw->mac_type <= e1000_82547_rev_2) return; + + temp = E1000_READ_REG(hw, IAC); + temp = E1000_READ_REG(hw, ICRXOC); + temp = E1000_READ_REG(hw, ICRXPTC); + temp = E1000_READ_REG(hw, ICRXATC); + temp = E1000_READ_REG(hw, ICTXPTC); + temp = E1000_READ_REG(hw, ICTXATC); + temp = E1000_READ_REG(hw, ICTXQEC); + temp = E1000_READ_REG(hw, ICTXQMTC); + temp = E1000_READ_REG(hw, ICRXDMTC); + } /****************************************************************************** @@ -4646,6 +5143,11 @@ e1000_get_bus_info(struct e1000_hw *hw) hw->bus_speed = e1000_bus_speed_unknown; hw->bus_width = e1000_bus_width_unknown; break; + case e1000_82573: + hw->bus_type = e1000_bus_type_pci_express; + hw->bus_speed = e1000_bus_speed_2500; + hw->bus_width = e1000_bus_width_pciex_4; + break; default: status = E1000_READ_REG(hw, STATUS); hw->bus_type = (status & E1000_STATUS_PCIX_MODE) ? @@ -4749,6 +5251,7 @@ e1000_get_cable_length(struct e1000_hw *hw, /* Use old method for Phy older than IGP */ if(hw->phy_type == e1000_phy_m88) { + ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if(ret_val) @@ -4865,7 +5368,8 @@ e1000_check_polarity(struct e1000_hw *hw, return ret_val; *polarity = (phy_data & M88E1000_PSSR_REV_POLARITY) >> M88E1000_PSSR_REV_POLARITY_SHIFT; - } else if(hw->phy_type == e1000_phy_igp) { + } else if(hw->phy_type == e1000_phy_igp || + hw->phy_type == e1000_phy_igp_2) { /* Read the Status register to check the speed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &phy_data); @@ -4917,7 +5421,8 @@ e1000_check_downshift(struct e1000_hw *hw) DEBUGFUNC("e1000_check_downshift"); - if(hw->phy_type == e1000_phy_igp) { + if(hw->phy_type == e1000_phy_igp || + hw->phy_type == e1000_phy_igp_2) { ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_LINK_HEALTH, &phy_data); if(ret_val) @@ -4933,6 +5438,7 @@ e1000_check_downshift(struct e1000_hw *hw) hw->speed_downgraded = (phy_data & M88E1000_PSSR_DOWNSHIFT) >> M88E1000_PSSR_DOWNSHIFT_SHIFT; } + return E1000_SUCCESS; } @@ -5047,7 +5553,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, if(ret_val) return ret_val; - msec_delay(20); + msec_delay_irq(20); ret_val = e1000_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIGA); @@ -5071,7 +5577,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, if(ret_val) return ret_val; - msec_delay(20); + msec_delay_irq(20); /* Now enable the transmitter */ ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); @@ -5096,7 +5602,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, if(ret_val) return ret_val; - msec_delay(20); + msec_delay_irq(20); ret_val = e1000_write_phy_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIGA); @@ -5112,7 +5618,7 @@ e1000_config_dsp_after_link_change(struct e1000_hw *hw, if(ret_val) return ret_val; - msec_delay(20); + msec_delay_irq(20); /* Now enable the transmitter */ ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); @@ -5187,22 +5693,36 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, uint16_t phy_data; DEBUGFUNC("e1000_set_d3_lplu_state"); - if(!((hw->mac_type == e1000_82541_rev_2) || - (hw->mac_type == e1000_82547_rev_2))) + if(hw->phy_type != e1000_phy_igp && hw->phy_type != e1000_phy_igp_2) return E1000_SUCCESS; /* During driver activity LPLU should not be used or it will attain link * from the lowest speeds starting from 10Mbps. The capability is used for * Dx transitions and states */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data); - if(ret_val) - return ret_val; - - if(!active) { - phy_data &= ~IGP01E1000_GMII_FLEX_SPD; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(hw->mac_type == e1000_82541_rev_2 || hw->mac_type == e1000_82547_rev_2) { + ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &phy_data); + if(ret_val) + return ret_val; + } else { + ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); if(ret_val) return ret_val; + } + + if(!active) { + if(hw->mac_type == e1000_82541_rev_2 || + hw->mac_type == e1000_82547_rev_2) { + phy_data &= ~IGP01E1000_GMII_FLEX_SPD; + ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(ret_val) + return ret_val; + } else { + phy_data &= ~IGP02E1000_PM_D3_LPLU; + ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, + phy_data); + if (ret_val) + return ret_val; + } /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during * Dx states where the power conservation is most important. During @@ -5236,11 +5756,105 @@ e1000_set_d3_lplu_state(struct e1000_hw *hw, (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_ALL ) || (hw->autoneg_advertised == AUTONEG_ADVERTISE_10_100_ALL)) { - phy_data |= IGP01E1000_GMII_FLEX_SPD; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(hw->mac_type == e1000_82541_rev_2 || + hw->mac_type == e1000_82547_rev_2) { + phy_data |= IGP01E1000_GMII_FLEX_SPD; + ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, phy_data); + if(ret_val) + return ret_val; + } else { + phy_data |= IGP02E1000_PM_D3_LPLU; + ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, + phy_data); + if (ret_val) + return ret_val; + } + + /* When LPLU is enabled we should disable SmartSpeed */ + ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); + if(ret_val) + return ret_val; + + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, phy_data); + if(ret_val) + return ret_val; + + } + return E1000_SUCCESS; +} + +/***************************************************************************** + * + * This function sets the lplu d0 state according to the active flag. When + * activating lplu this function also disables smart speed and vise versa. + * lplu will not be activated unless the device autonegotiation advertisment + * meets standards of either 10 or 10/100 or 10/100/1000 at all duplexes. + * hw: Struct containing variables accessed by shared code + * active - true to enable lplu false to disable lplu. + * + * returns: - E1000_ERR_PHY if fail to read/write the PHY + * E1000_SUCCESS at any other case. + * + ****************************************************************************/ + +int32_t +e1000_set_d0_lplu_state(struct e1000_hw *hw, + boolean_t active) +{ + int32_t ret_val; + uint16_t phy_data; + DEBUGFUNC("e1000_set_d0_lplu_state"); + + if(hw->mac_type <= e1000_82547_rev_2) + return E1000_SUCCESS; + + ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data); if(ret_val) return ret_val; + if (!active) { + phy_data &= ~IGP02E1000_PM_D0_LPLU; + ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); + if (ret_val) + return ret_val; + + /* LPLU and SmartSpeed are mutually exclusive. LPLU is used during + * Dx states where the power conservation is most important. During + * driver activity we should enable SmartSpeed, so performance is + * maintained. */ + if (hw->smart_speed == e1000_smart_speed_on) { + ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data); + if(ret_val) + return ret_val; + + phy_data |= IGP01E1000_PSCFR_SMART_SPEED; + ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + } else if (hw->smart_speed == e1000_smart_speed_off) { + ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &phy_data); + if (ret_val) + return ret_val; + + phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED; + ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + phy_data); + if(ret_val) + return ret_val; + } + + + } else { + + phy_data |= IGP02E1000_PM_D0_LPLU; + ret_val = e1000_write_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, phy_data); + if (ret_val) + return ret_val; + /* When LPLU is enabled we should disable SmartSpeed */ ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &phy_data); if(ret_val) @@ -5318,18 +5932,350 @@ e1000_set_vco_speed(struct e1000_hw *hw) return E1000_SUCCESS; } -static int32_t -e1000_polarity_reversal_workaround(struct e1000_hw *hw) -{ - int32_t ret_val; - uint16_t mii_status_reg; - uint16_t i; - /* Polarity reversal workaround for forced 10F/10H links. */ +/***************************************************************************** + * This function reads the cookie from ARC ram. + * + * returns: - E1000_SUCCESS . + ****************************************************************************/ +int32_t +e1000_host_if_read_cookie(struct e1000_hw * hw, uint8_t *buffer) +{ + uint8_t i; + uint32_t offset = E1000_MNG_DHCP_COOKIE_OFFSET; + uint8_t length = E1000_MNG_DHCP_COOKIE_LENGTH; - /* Disable the transmitter on the PHY */ + length = (length >> 2); + offset = (offset >> 2); - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); + for (i = 0; i < length; i++) { + *((uint32_t *) buffer + i) = + E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset + i); + } + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function checks whether the HOST IF is enabled for command operaton + * and also checks whether the previous command is completed. + * It busy waits in case of previous command is not completed. + * + * returns: - E1000_ERR_HOST_INTERFACE_COMMAND in case if is not ready or + * timeout + * - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +e1000_mng_enable_host_if(struct e1000_hw * hw) +{ + uint32_t hicr; + uint8_t i; + + /* Check that the host interface is enabled. */ + hicr = E1000_READ_REG(hw, HICR); + if ((hicr & E1000_HICR_EN) == 0) { + DEBUGOUT("E1000_HOST_EN bit disabled.\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + /* check the previous command is completed */ + for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { + hicr = E1000_READ_REG(hw, HICR); + if (!(hicr & E1000_HICR_C)) + break; + msec_delay_irq(1); + } + + if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { + DEBUGOUT("Previous command timeout failed .\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + return E1000_SUCCESS; +} + +/***************************************************************************** + * This function writes the buffer content at the offset given on the host if. + * It also does alignment considerations to do the writes in most efficient way. + * Also fills up the sum of the buffer in *buffer parameter. + * + * returns - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer, + uint16_t length, uint16_t offset, uint8_t *sum) +{ + uint8_t *tmp; + uint8_t *bufptr = buffer; + uint32_t data; + uint16_t remaining, i, j, prev_bytes; + + /* sum = only sum of the data and it is not checksum */ + + if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) { + return -E1000_ERR_PARAM; + } + + tmp = (uint8_t *)&data; + prev_bytes = offset & 0x3; + offset &= 0xFFFC; + offset >>= 2; + + if (prev_bytes) { + data = E1000_READ_REG_ARRAY_DWORD(hw, HOST_IF, offset); + for (j = prev_bytes; j < sizeof(uint32_t); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset, data); + length -= j - prev_bytes; + offset++; + } + + remaining = length & 0x3; + length -= remaining; + + /* Calculate length in DWORDs */ + length >>= 2; + + /* The device driver writes the relevant command block into the + * ram area. */ + for (i = 0; i < length; i++) { + for (j = 0; j < sizeof(uint32_t); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data); + } + if (remaining) { + for (j = 0; j < sizeof(uint32_t); j++) { + if (j < remaining) + *(tmp + j) = *bufptr++; + else + *(tmp + j) = 0; + + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, offset + i, data); + } + + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function writes the command header after does the checksum calculation. + * + * returns - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +e1000_mng_write_cmd_header(struct e1000_hw * hw, + struct e1000_host_mng_command_header * hdr) +{ + uint16_t i; + uint8_t sum; + uint8_t *buffer; + + /* Write the whole command header structure which includes sum of + * the buffer */ + + uint16_t length = sizeof(struct e1000_host_mng_command_header); + + sum = hdr->checksum; + hdr->checksum = 0; + + buffer = (uint8_t *) hdr; + i = length; + while(i--) + sum += buffer[i]; + + hdr->checksum = 0 - sum; + + length >>= 2; + /* The device driver writes the relevant command block into the ram area. */ + for (i = 0; i < length; i++) + E1000_WRITE_REG_ARRAY_DWORD(hw, HOST_IF, i, *((uint32_t *) hdr + i)); + + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function indicates to ARC that a new command is pending which completes + * one write operation by the driver. + * + * returns - E1000_SUCCESS for success. + ****************************************************************************/ +int32_t +e1000_mng_write_commit( + struct e1000_hw * hw) +{ + uint32_t hicr; + + hicr = E1000_READ_REG(hw, HICR); + /* Setting this bit tells the ARC that a new command is pending. */ + E1000_WRITE_REG(hw, HICR, hicr | E1000_HICR_C); + + return E1000_SUCCESS; +} + + +/***************************************************************************** + * This function checks the mode of the firmware. + * + * returns - TRUE when the mode is IAMT or FALSE. + ****************************************************************************/ +boolean_t +e1000_check_mng_mode( + struct e1000_hw *hw) +{ + uint32_t fwsm; + + fwsm = E1000_READ_REG(hw, FWSM); + + if((fwsm & E1000_FWSM_MODE_MASK) == + (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT)) + return TRUE; + + return FALSE; +} + + +/***************************************************************************** + * This function writes the dhcp info . + ****************************************************************************/ +int32_t +e1000_mng_write_dhcp_info(struct e1000_hw * hw, uint8_t *buffer, + uint16_t length) +{ + int32_t ret_val; + struct e1000_host_mng_command_header hdr; + + hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; + hdr.command_length = length; + hdr.reserved1 = 0; + hdr.reserved2 = 0; + hdr.checksum = 0; + + ret_val = e1000_mng_enable_host_if(hw); + if (ret_val == E1000_SUCCESS) { + ret_val = e1000_mng_host_if_write(hw, buffer, length, sizeof(hdr), + &(hdr.checksum)); + if (ret_val == E1000_SUCCESS) { + ret_val = e1000_mng_write_cmd_header(hw, &hdr); + if (ret_val == E1000_SUCCESS) + ret_val = e1000_mng_write_commit(hw); + } + } + return ret_val; +} + + +/***************************************************************************** + * This function calculates the checksum. + * + * returns - checksum of buffer contents. + ****************************************************************************/ +uint8_t +e1000_calculate_mng_checksum(char *buffer, uint32_t length) +{ + uint8_t sum = 0; + uint32_t i; + + if (!buffer) + return 0; + + for (i=0; i < length; i++) + sum += buffer[i]; + + return (uint8_t) (0 - sum); +} + +/***************************************************************************** + * This function checks whether tx pkt filtering needs to be enabled or not. + * + * returns - TRUE for packet filtering or FALSE. + ****************************************************************************/ +boolean_t +e1000_enable_tx_pkt_filtering(struct e1000_hw *hw) +{ + /* called in init as well as watchdog timer functions */ + + int32_t ret_val, checksum; + boolean_t tx_filter = FALSE; + struct e1000_host_mng_dhcp_cookie *hdr = &(hw->mng_cookie); + uint8_t *buffer = (uint8_t *) &(hw->mng_cookie); + + if (e1000_check_mng_mode(hw)) { + ret_val = e1000_mng_enable_host_if(hw); + if (ret_val == E1000_SUCCESS) { + ret_val = e1000_host_if_read_cookie(hw, buffer); + if (ret_val == E1000_SUCCESS) { + checksum = hdr->checksum; + hdr->checksum = 0; + if ((hdr->signature == E1000_IAMT_SIGNATURE) && + checksum == e1000_calculate_mng_checksum((char *)buffer, + E1000_MNG_DHCP_COOKIE_LENGTH)) { + if (hdr->status & + E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT) + tx_filter = TRUE; + } else + tx_filter = TRUE; + } else + tx_filter = TRUE; + } + } + + hw->tx_pkt_filtering = tx_filter; + return tx_filter; +} + +/****************************************************************************** + * Verifies the hardware needs to allow ARPs to be processed by the host + * + * hw - Struct containing variables accessed by shared code + * + * returns: - TRUE/FALSE + * + *****************************************************************************/ +uint32_t +e1000_enable_mng_pass_thru(struct e1000_hw *hw) +{ + uint32_t manc; + uint32_t fwsm, factps; + + if (hw->asf_firmware_present) { + manc = E1000_READ_REG(hw, MANC); + + if (!(manc & E1000_MANC_RCV_TCO_EN) || + !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) + return FALSE; + if (e1000_arc_subsystem_valid(hw) == TRUE) { + fwsm = E1000_READ_REG(hw, FWSM); + factps = E1000_READ_REG(hw, FACTPS); + + if (((fwsm & E1000_FWSM_MODE_MASK) == + (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT)) && + (factps & E1000_FACTPS_MNGCG)) + return TRUE; + } else + if ((manc & E1000_MANC_SMBUS_EN) && !(manc & E1000_MANC_ASF_EN)) + return TRUE; + } + return FALSE; +} + +static int32_t +e1000_polarity_reversal_workaround(struct e1000_hw *hw) +{ + int32_t ret_val; + uint16_t mii_status_reg; + uint16_t i; + + /* Polarity reversal workaround for forced 10F/10H links. */ + + /* Disable the transmitter on the PHY */ + + ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); if(ret_val) return ret_val; ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF); @@ -5403,3 +6349,265 @@ e1000_polarity_reversal_workaround(struct e1000_hw *hw) return E1000_SUCCESS; } +/*************************************************************************** + * + * Disables PCI-Express master access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - none. + * + ***************************************************************************/ +void +e1000_set_pci_express_master_disable(struct e1000_hw *hw) +{ + uint32_t ctrl; + + DEBUGFUNC("e1000_set_pci_express_master_disable"); + + if (hw->bus_type != e1000_bus_type_pci_express) + return; + + ctrl = E1000_READ_REG(hw, CTRL); + ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; + E1000_WRITE_REG(hw, CTRL, ctrl); +} + +/*************************************************************************** + * + * Enables PCI-Express master access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - none. + * + ***************************************************************************/ +void +e1000_enable_pciex_master(struct e1000_hw *hw) +{ + uint32_t ctrl; + + DEBUGFUNC("e1000_enable_pciex_master"); + + if (hw->bus_type != e1000_bus_type_pci_express) + return; + + ctrl = E1000_READ_REG(hw, CTRL); + ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE; + E1000_WRITE_REG(hw, CTRL, ctrl); +} + +/******************************************************************************* + * + * Disables PCI-Express master access and verifies there are no pending requests + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_MASTER_REQUESTS_PENDING if master disable bit hasn't + * caused the master requests to be disabled. + * E1000_SUCCESS master requests disabled. + * + ******************************************************************************/ +int32_t +e1000_disable_pciex_master(struct e1000_hw *hw) +{ + int32_t timeout = MASTER_DISABLE_TIMEOUT; /* 80ms */ + + DEBUGFUNC("e1000_disable_pciex_master"); + + if (hw->bus_type != e1000_bus_type_pci_express) + return E1000_SUCCESS; + + e1000_set_pci_express_master_disable(hw); + + while(timeout) { + if(!(E1000_READ_REG(hw, STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) + break; + else + udelay(100); + timeout--; + } + + if(!timeout) { + DEBUGOUT("Master requests are pending.\n"); + return -E1000_ERR_MASTER_REQUESTS_PENDING; + } + + return E1000_SUCCESS; +} + +/******************************************************************************* + * + * Check for EEPROM Auto Read bit done. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_RESET if fail to reset MAC + * E1000_SUCCESS at any other case. + * + ******************************************************************************/ +int32_t +e1000_get_auto_rd_done(struct e1000_hw *hw) +{ + int32_t timeout = AUTO_READ_DONE_TIMEOUT; + + DEBUGFUNC("e1000_get_auto_rd_done"); + + switch (hw->mac_type) { + default: + msec_delay(5); + break; + case e1000_82573: + while(timeout) { + if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break; + else msec_delay(1); + timeout--; + } + + if(!timeout) { + DEBUGOUT("Auto read by HW from EEPROM has not completed.\n"); + return -E1000_ERR_RESET; + } + break; + } + + return E1000_SUCCESS; +} + +/*************************************************************************** + * Checks if the PHY configuration is done + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_RESET if fail to reset MAC + * E1000_SUCCESS at any other case. + * + ***************************************************************************/ +int32_t +e1000_get_phy_cfg_done(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_get_phy_cfg_done"); + + /* Simply wait for 10ms */ + msec_delay(10); + + return E1000_SUCCESS; +} + +/*************************************************************************** + * + * Using the combination of SMBI and SWESMBI semaphore bits when resetting + * adapter or Eeprom access. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - E1000_ERR_EEPROM if fail to access EEPROM. + * E1000_SUCCESS at any other case. + * + ***************************************************************************/ +int32_t +e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) +{ + int32_t timeout; + uint32_t swsm; + + DEBUGFUNC("e1000_get_hw_eeprom_semaphore"); + + if(!hw->eeprom_semaphore_present) + return E1000_SUCCESS; + + + /* Get the FW semaphore. */ + timeout = hw->eeprom.word_size + 1; + while(timeout) { + swsm = E1000_READ_REG(hw, SWSM); + swsm |= E1000_SWSM_SWESMBI; + E1000_WRITE_REG(hw, SWSM, swsm); + /* if we managed to set the bit we got the semaphore. */ + swsm = E1000_READ_REG(hw, SWSM); + if(swsm & E1000_SWSM_SWESMBI) + break; + + udelay(50); + timeout--; + } + + if(!timeout) { + /* Release semaphores */ + e1000_put_hw_eeprom_semaphore(hw); + DEBUGOUT("Driver can't access the Eeprom - SWESMBI bit is set.\n"); + return -E1000_ERR_EEPROM; + } + + return E1000_SUCCESS; +} + +/*************************************************************************** + * This function clears HW semaphore bits. + * + * hw: Struct containing variables accessed by shared code + * + * returns: - None. + * + ***************************************************************************/ +void +e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) +{ + uint32_t swsm; + + DEBUGFUNC("e1000_put_hw_eeprom_semaphore"); + + if(!hw->eeprom_semaphore_present) + return; + + swsm = E1000_READ_REG(hw, SWSM); + /* Release both semaphores. */ + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + E1000_WRITE_REG(hw, SWSM, swsm); +} + +/****************************************************************************** + * Checks if PHY reset is blocked due to SOL/IDER session, for example. + * Returning E1000_BLK_PHY_RESET isn't necessarily an error. But it's up to + * the caller to figure out how to deal with it. + * + * hw - Struct containing variables accessed by shared code + * + * returns: - E1000_BLK_PHY_RESET + * E1000_SUCCESS + * + *****************************************************************************/ +int32_t +e1000_check_phy_reset_block(struct e1000_hw *hw) +{ + uint32_t manc = 0; + if(hw->mac_type > e1000_82547_rev_2) + manc = E1000_READ_REG(hw, MANC); + return (manc & E1000_MANC_BLK_PHY_RST_ON_IDE) ? + E1000_BLK_PHY_RESET : E1000_SUCCESS; +} + +uint8_t +e1000_arc_subsystem_valid(struct e1000_hw *hw) +{ + uint32_t fwsm; + + /* On 8257x silicon, registers in the range of 0x8800 - 0x8FFC + * may not be provided a DMA clock when no manageability features are + * enabled. We do not want to perform any reads/writes to these registers + * if this is the case. We read FWSM to determine the manageability mode. + */ + switch (hw->mac_type) { + case e1000_82573: + fwsm = E1000_READ_REG(hw, FWSM); + if((fwsm & E1000_FWSM_MODE_MASK) != 0) + return TRUE; + break; + default: + break; + } + return FALSE; +} + + + diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index f397e637a3c5..1573f608fb68 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -57,6 +57,7 @@ typedef enum { e1000_82541_rev_2, e1000_82547, e1000_82547_rev_2, + e1000_82573, e1000_num_macs } e1000_mac_type; @@ -64,6 +65,7 @@ typedef enum { e1000_eeprom_uninitialized = 0, e1000_eeprom_spi, e1000_eeprom_microwire, + e1000_eeprom_flash, e1000_num_eeprom_types } e1000_eeprom_type; @@ -96,6 +98,7 @@ typedef enum { e1000_bus_type_unknown = 0, e1000_bus_type_pci, e1000_bus_type_pcix, + e1000_bus_type_pci_express, e1000_bus_type_reserved } e1000_bus_type; @@ -107,6 +110,7 @@ typedef enum { e1000_bus_speed_100, e1000_bus_speed_120, e1000_bus_speed_133, + e1000_bus_speed_2500, e1000_bus_speed_reserved } e1000_bus_speed; @@ -115,6 +119,8 @@ typedef enum { e1000_bus_width_unknown = 0, e1000_bus_width_32, e1000_bus_width_64, + e1000_bus_width_pciex_1, + e1000_bus_width_pciex_4, e1000_bus_width_reserved } e1000_bus_width; @@ -196,6 +202,7 @@ typedef enum { typedef enum { e1000_phy_m88 = 0, e1000_phy_igp, + e1000_phy_igp_2, e1000_phy_undefined = 0xFF } e1000_phy_type; @@ -242,8 +249,19 @@ struct e1000_eeprom_info { uint16_t address_bits; uint16_t delay_usec; uint16_t page_size; + boolean_t use_eerd; + boolean_t use_eewr; }; +/* Flex ASF Information */ +#define E1000_HOST_IF_MAX_SIZE 2048 + +typedef enum { + e1000_byte_align = 0, + e1000_word_align = 1, + e1000_dword_align = 2 +} e1000_align_type; + /* Error Codes */ @@ -254,11 +272,16 @@ struct e1000_eeprom_info { #define E1000_ERR_PARAM 4 #define E1000_ERR_MAC_TYPE 5 #define E1000_ERR_PHY_TYPE 6 +#define E1000_ERR_RESET 9 +#define E1000_ERR_MASTER_REQUESTS_PENDING 10 +#define E1000_ERR_HOST_INTERFACE_COMMAND 11 +#define E1000_BLK_PHY_RESET 12 /* Function prototypes */ /* Initialization */ int32_t e1000_reset_hw(struct e1000_hw *hw); int32_t e1000_init_hw(struct e1000_hw *hw); +int32_t e1000_id_led_init(struct e1000_hw * hw); int32_t e1000_set_mac_type(struct e1000_hw *hw); void e1000_set_media_type(struct e1000_hw *hw); @@ -275,7 +298,7 @@ int32_t e1000_force_mac_fc(struct e1000_hw *hw); /* PHY */ int32_t e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t *phy_data); int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data); -void e1000_phy_hw_reset(struct e1000_hw *hw); +int32_t e1000_phy_hw_reset(struct e1000_hw *hw); int32_t e1000_phy_reset(struct e1000_hw *hw); int32_t e1000_detect_gig_phy(struct e1000_hw *hw); int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info); @@ -287,13 +310,86 @@ int32_t e1000_check_downshift(struct e1000_hw *hw); int32_t e1000_validate_mdi_setting(struct e1000_hw *hw); /* EEPROM Functions */ -void e1000_init_eeprom_params(struct e1000_hw *hw); +int32_t e1000_init_eeprom_params(struct e1000_hw *hw); +boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw); +int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data); +int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data); +int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd); + +/* MNG HOST IF functions */ +uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw); + +#define E1000_MNG_DHCP_TX_PAYLOAD_CMD 64 +#define E1000_HI_MAX_MNG_DATA_LENGTH 0x6F8 /* Host Interface data length */ + +#define E1000_MNG_DHCP_COMMAND_TIMEOUT 10 /* Time in ms to process MNG command */ +#define E1000_MNG_DHCP_COOKIE_OFFSET 0x6F0 /* Cookie offset */ +#define E1000_MNG_DHCP_COOKIE_LENGTH 0x10 /* Cookie length */ +#define E1000_MNG_IAMT_MODE 0x3 +#define E1000_IAMT_SIGNATURE 0x544D4149 /* Intel(R) Active Management Technology signature */ + +#define E1000_MNG_DHCP_COOKIE_STATUS_PARSING_SUPPORT 0x1 /* DHCP parsing enabled */ +#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT 0x2 /* DHCP parsing enabled */ +#define E1000_VFTA_ENTRY_SHIFT 0x5 +#define E1000_VFTA_ENTRY_MASK 0x7F +#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F + +struct e1000_host_mng_command_header { + uint8_t command_id; + uint8_t checksum; + uint16_t reserved1; + uint16_t reserved2; + uint16_t command_length; +}; + +struct e1000_host_mng_command_info { + struct e1000_host_mng_command_header command_header; /* Command Head/Command Result Head has 4 bytes */ + uint8_t command_data[E1000_HI_MAX_MNG_DATA_LENGTH]; /* Command data can length 0..0x658*/ +}; +#ifdef __BIG_ENDIAN +struct e1000_host_mng_dhcp_cookie{ + uint32_t signature; + uint16_t vlan_id; + uint8_t reserved0; + uint8_t status; + uint32_t reserved1; + uint8_t checksum; + uint8_t reserved3; + uint16_t reserved2; +}; +#else +struct e1000_host_mng_dhcp_cookie{ + uint32_t signature; + uint8_t status; + uint8_t reserved0; + uint16_t vlan_id; + uint32_t reserved1; + uint16_t reserved2; + uint8_t reserved3; + uint8_t checksum; +}; +#endif + +int32_t e1000_mng_write_dhcp_info(struct e1000_hw *hw, uint8_t *buffer, + uint16_t length); +boolean_t e1000_check_mng_mode(struct e1000_hw *hw); +boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw); +int32_t e1000_mng_enable_host_if(struct e1000_hw *hw); +int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer, + uint16_t length, uint16_t offset, uint8_t *sum); +int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, + struct e1000_host_mng_command_header* hdr); + +int32_t e1000_mng_write_commit(struct e1000_hw *hw); + int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw); int32_t e1000_update_eeprom_checksum(struct e1000_hw *hw); int32_t e1000_write_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data); int32_t e1000_read_part_num(struct e1000_hw *hw, uint32_t * part_num); int32_t e1000_read_mac_addr(struct e1000_hw * hw); +int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask); +void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask); /* Filters (multicast, vlan, receive) */ void e1000_init_rx_addrs(struct e1000_hw *hw); @@ -313,7 +409,6 @@ int32_t e1000_led_off(struct e1000_hw *hw); /* Adaptive IFS Functions */ /* Everything else */ -uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw); void e1000_clear_hw_cntrs(struct e1000_hw *hw); void e1000_reset_adaptive(struct e1000_hw *hw); void e1000_update_adaptive(struct e1000_hw *hw); @@ -330,6 +425,19 @@ void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value); void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value); int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up); int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); +int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active); +void e1000_set_pci_express_master_disable(struct e1000_hw *hw); +void e1000_enable_pciex_master(struct e1000_hw *hw); +int32_t e1000_disable_pciex_master(struct e1000_hw *hw); +int32_t e1000_get_auto_rd_done(struct e1000_hw *hw); +int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw); +int32_t e1000_get_software_semaphore(struct e1000_hw *hw); +void e1000_release_software_semaphore(struct e1000_hw *hw); +int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); +int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw); +void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw); +int32_t e1000_commit_shadow_ram(struct e1000_hw *hw); +uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw); #define E1000_READ_REG_IO(a, reg) \ e1000_read_reg_io((a), E1000_##reg) @@ -369,6 +477,10 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); #define E1000_DEV_ID_82546GB_SERDES 0x107B #define E1000_DEV_ID_82546GB_PCIE 0x108A #define E1000_DEV_ID_82547EI 0x1019 +#define E1000_DEV_ID_82573E 0x108B +#define E1000_DEV_ID_82573E_IAMT 0x108C + +#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 @@ -381,6 +493,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); #define E1000_REVISION_0 0 #define E1000_REVISION_1 1 #define E1000_REVISION_2 2 +#define E1000_REVISION_3 3 #define SPEED_10 10 #define SPEED_100 100 @@ -437,6 +550,7 @@ int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active); E1000_IMS_RXSEQ | \ E1000_IMS_LSC) + /* Number of high/low register pairs in the RAR. The RAR (Receive Address * Registers) holds the directed and multicast addresses that we monitor. We * reserve one of these spots for our directed address, allowing us room for @@ -457,14 +571,74 @@ struct e1000_rx_desc { uint16_t special; }; +/* Receive Descriptor - Extended */ +union e1000_rx_desc_extended { + struct { + uint64_t buffer_addr; + uint64_t reserved; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx Queues */ + union { + uint32_t rss; /* RSS Hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length; + uint16_t vlan; /* VLAN tag */ + } upper; + } wb; /* writeback */ +}; + +#define MAX_PS_BUFFERS 4 +/* Receive Descriptor - Packet Split */ +union e1000_rx_desc_packet_split { + struct { + /* one buffer for protocol header(s), three data buffers */ + uint64_t buffer_addr[MAX_PS_BUFFERS]; + } read; + struct { + struct { + uint32_t mrq; /* Multiple Rx Queues */ + union { + uint32_t rss; /* RSS Hash */ + struct { + uint16_t ip_id; /* IP id */ + uint16_t csum; /* Packet Checksum */ + } csum_ip; + } hi_dword; + } lower; + struct { + uint32_t status_error; /* ext status/error */ + uint16_t length0; /* length of buffer 0 */ + uint16_t vlan; /* VLAN tag */ + } middle; + struct { + uint16_t header_status; + uint16_t length[3]; /* length of buffers 1-3 */ + } upper; + uint64_t reserved; + } wb; /* writeback */ +}; + /* Receive Decriptor bit definitions */ #define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */ #define E1000_RXD_STAT_EOP 0x02 /* End of Packet */ #define E1000_RXD_STAT_IXSM 0x04 /* Ignore checksum */ #define E1000_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ +#define E1000_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ #define E1000_RXD_STAT_TCPCS 0x20 /* TCP xsum calculated */ #define E1000_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ #define E1000_RXD_STAT_PIF 0x80 /* passed in-exact filter */ +#define E1000_RXD_STAT_IPIDV 0x200 /* IP identification valid */ +#define E1000_RXD_STAT_UDPV 0x400 /* Valid UDP checksum */ +#define E1000_RXD_STAT_ACK 0x8000 /* ACK Packet indication */ #define E1000_RXD_ERR_CE 0x01 /* CRC Error */ #define E1000_RXD_ERR_SE 0x02 /* Symbol Error */ #define E1000_RXD_ERR_SEQ 0x04 /* Sequence Error */ @@ -474,9 +648,20 @@ struct e1000_rx_desc { #define E1000_RXD_ERR_RXE 0x80 /* Rx Data Error */ #define E1000_RXD_SPC_VLAN_MASK 0x0FFF /* VLAN ID is in lower 12 bits */ #define E1000_RXD_SPC_PRI_MASK 0xE000 /* Priority is in upper 3 bits */ -#define E1000_RXD_SPC_PRI_SHIFT 0x000D /* Priority is in upper 3 of 16 */ +#define E1000_RXD_SPC_PRI_SHIFT 13 #define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ -#define E1000_RXD_SPC_CFI_SHIFT 0x000C /* CFI is bit 12 */ +#define E1000_RXD_SPC_CFI_SHIFT 12 + +#define E1000_RXDEXT_STATERR_CE 0x01000000 +#define E1000_RXDEXT_STATERR_SE 0x02000000 +#define E1000_RXDEXT_STATERR_SEQ 0x04000000 +#define E1000_RXDEXT_STATERR_CXE 0x10000000 +#define E1000_RXDEXT_STATERR_TCPE 0x20000000 +#define E1000_RXDEXT_STATERR_IPE 0x40000000 +#define E1000_RXDEXT_STATERR_RXE 0x80000000 + +#define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 +#define E1000_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF /* mask to determine if packets should be dropped due to frame errors */ #define E1000_RXD_ERR_FRAME_ERR_MASK ( \ @@ -486,6 +671,15 @@ struct e1000_rx_desc { E1000_RXD_ERR_CXE | \ E1000_RXD_ERR_RXE) + +/* Same mask, but for extended and packet split descriptors */ +#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \ + E1000_RXDEXT_STATERR_CE | \ + E1000_RXDEXT_STATERR_SE | \ + E1000_RXDEXT_STATERR_SEQ | \ + E1000_RXDEXT_STATERR_CXE | \ + E1000_RXDEXT_STATERR_RXE) + /* Transmit Descriptor */ struct e1000_tx_desc { uint64_t buffer_addr; /* Address of the descriptor's data buffer */ @@ -667,6 +861,7 @@ struct e1000_ffvt_entry { #define E1000_ICS 0x000C8 /* Interrupt Cause Set - WO */ #define E1000_IMS 0x000D0 /* Interrupt Mask Set - RW */ #define E1000_IMC 0x000D8 /* Interrupt Mask Clear - WO */ +#define E1000_IAM 0x000E0 /* Interrupt Acknowledge Auto Mask */ #define E1000_RCTL 0x00100 /* RX Control - RW */ #define E1000_FCTTV 0x00170 /* Flow Control Transmit Timer Value - RW */ #define E1000_TXCW 0x00178 /* TX Configuration Word - RW */ @@ -676,9 +871,23 @@ struct e1000_ffvt_entry { #define E1000_TBT 0x00448 /* TX Burst Timer - RW */ #define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */ #define E1000_LEDCTL 0x00E00 /* LED Control - RW */ +#define E1000_EXTCNF_CTRL 0x00F00 /* Extended Configuration Control */ +#define E1000_EXTCNF_SIZE 0x00F08 /* Extended Configuration Size */ #define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */ +#define E1000_PBS 0x01008 /* Packet Buffer Size */ +#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */ +#define E1000_FLASH_UPDATES 1000 +#define E1000_EEARBC 0x01024 /* EEPROM Auto Read Bus Control */ +#define E1000_FLASHT 0x01028 /* FLASH Timer Register */ +#define E1000_EEWR 0x0102C /* EEPROM Write Register - RW */ +#define E1000_FLSWCTL 0x01030 /* FLASH control register */ +#define E1000_FLSWDATA 0x01034 /* FLASH data register */ +#define E1000_FLSWCNT 0x01038 /* FLASH Access Counter */ +#define E1000_FLOP 0x0103C /* FLASH Opcode Register */ +#define E1000_ERT 0x02008 /* Early Rx Threshold - RW */ #define E1000_FCRTL 0x02160 /* Flow Control Receive Threshold Low - RW */ #define E1000_FCRTH 0x02168 /* Flow Control Receive Threshold High - RW */ +#define E1000_PSRCTL 0x02170 /* Packet Split Receive Control - RW */ #define E1000_RDBAL 0x02800 /* RX Descriptor Base Address Low - RW */ #define E1000_RDBAH 0x02804 /* RX Descriptor Base Address High - RW */ #define E1000_RDLEN 0x02808 /* RX Descriptor Length - RW */ @@ -688,6 +897,7 @@ struct e1000_ffvt_entry { #define E1000_RXDCTL 0x02828 /* RX Descriptor Control - RW */ #define E1000_RADV 0x0282C /* RX Interrupt Absolute Delay Timer - RW */ #define E1000_RSRPD 0x02C00 /* RX Small Packet Detect - RW */ +#define E1000_RAID 0x02C08 /* Receive Ack Interrupt Delay - RW */ #define E1000_TXDMAC 0x03000 /* TX DMA Control - RW */ #define E1000_TDFH 0x03410 /* TX Data FIFO Head - RW */ #define E1000_TDFT 0x03418 /* TX Data FIFO Tail - RW */ @@ -703,6 +913,14 @@ struct e1000_ffvt_entry { #define E1000_TXDCTL 0x03828 /* TX Descriptor Control - RW */ #define E1000_TADV 0x0382C /* TX Interrupt Absolute Delay Val - RW */ #define E1000_TSPMT 0x03830 /* TCP Segmentation PAD & Min Threshold - RW */ +#define E1000_TARC0 0x03840 /* TX Arbitration Count (0) */ +#define E1000_TDBAL1 0x03900 /* TX Desc Base Address Low (1) - RW */ +#define E1000_TDBAH1 0x03904 /* TX Desc Base Address High (1) - RW */ +#define E1000_TDLEN1 0x03908 /* TX Desc Length (1) - RW */ +#define E1000_TDH1 0x03910 /* TX Desc Head (1) - RW */ +#define E1000_TDT1 0x03918 /* TX Desc Tail (1) - RW */ +#define E1000_TXDCTL1 0x03928 /* TX Descriptor Control (1) - RW */ +#define E1000_TARC1 0x03940 /* TX Arbitration Count (1) */ #define E1000_CRCERRS 0x04000 /* CRC Error Count - R/clr */ #define E1000_ALGNERRC 0x04004 /* Alignment Error Count - R/clr */ #define E1000_SYMERRS 0x04008 /* Symbol Error Count - R/clr */ @@ -761,7 +979,17 @@ struct e1000_ffvt_entry { #define E1000_BPTC 0x040F4 /* Broadcast Packets TX Count - R/clr */ #define E1000_TSCTC 0x040F8 /* TCP Segmentation Context TX - R/clr */ #define E1000_TSCTFC 0x040FC /* TCP Segmentation Context TX Fail - R/clr */ +#define E1000_IAC 0x4100 /* Interrupt Assertion Count */ +#define E1000_ICRXPTC 0x4104 /* Interrupt Cause Rx Packet Timer Expire Count */ +#define E1000_ICRXATC 0x4108 /* Interrupt Cause Rx Absolute Timer Expire Count */ +#define E1000_ICTXPTC 0x410C /* Interrupt Cause Tx Packet Timer Expire Count */ +#define E1000_ICTXATC 0x4110 /* Interrupt Cause Tx Absolute Timer Expire Count */ +#define E1000_ICTXQEC 0x4118 /* Interrupt Cause Tx Queue Empty Count */ +#define E1000_ICTXQMTC 0x411C /* Interrupt Cause Tx Queue Minimum Threshold Count */ +#define E1000_ICRXDMTC 0x4120 /* Interrupt Cause Rx Descriptor Minimum Threshold Count */ +#define E1000_ICRXOC 0x4124 /* Interrupt Cause Receiver Overrun Count */ #define E1000_RXCSUM 0x05000 /* RX Checksum Control - RW */ +#define E1000_RFCTL 0x05008 /* Receive Filter Control*/ #define E1000_MTA 0x05200 /* Multicast Table Array - RW Array */ #define E1000_RA 0x05400 /* Receive Address - RW Array */ #define E1000_VFTA 0x05600 /* VLAN Filter Table Array - RW Array */ @@ -779,6 +1007,16 @@ struct e1000_ffvt_entry { #define E1000_FFMT 0x09000 /* Flexible Filter Mask Table - RW Array */ #define E1000_FFVT 0x09800 /* Flexible Filter Value Table - RW Array */ +#define E1000_GCR 0x05B00 /* PCI-Ex Control */ +#define E1000_GSCL_1 0x05B10 /* PCI-Ex Statistic Control #1 */ +#define E1000_GSCL_2 0x05B14 /* PCI-Ex Statistic Control #2 */ +#define E1000_GSCL_3 0x05B18 /* PCI-Ex Statistic Control #3 */ +#define E1000_GSCL_4 0x05B1C /* PCI-Ex Statistic Control #4 */ +#define E1000_FACTPS 0x05B30 /* Function Active and Power State to MNG */ +#define E1000_SWSM 0x05B50 /* SW Semaphore */ +#define E1000_FWSM 0x05B54 /* FW Semaphore */ +#define E1000_FFLT_DBG 0x05F04 /* Debug Register */ +#define E1000_HICR 0x08F00 /* Host Inteface Control */ /* Register Set (82542) * * Some of the 82542 registers are located at different offsets than they are @@ -829,6 +1067,18 @@ struct e1000_ffvt_entry { #define E1000_82542_VFTA 0x00600 #define E1000_82542_LEDCTL E1000_LEDCTL #define E1000_82542_PBA E1000_PBA +#define E1000_82542_PBS E1000_PBS +#define E1000_82542_EEMNGCTL E1000_EEMNGCTL +#define E1000_82542_EEARBC E1000_EEARBC +#define E1000_82542_FLASHT E1000_FLASHT +#define E1000_82542_EEWR E1000_EEWR +#define E1000_82542_FLSWCTL E1000_FLSWCTL +#define E1000_82542_FLSWDATA E1000_FLSWDATA +#define E1000_82542_FLSWCNT E1000_FLSWCNT +#define E1000_82542_FLOP E1000_FLOP +#define E1000_82542_EXTCNF_CTRL E1000_EXTCNF_CTRL +#define E1000_82542_EXTCNF_SIZE E1000_EXTCNF_SIZE +#define E1000_82542_ERT E1000_ERT #define E1000_82542_RXDCTL E1000_RXDCTL #define E1000_82542_RADV E1000_RADV #define E1000_82542_RSRPD E1000_RSRPD @@ -913,6 +1163,38 @@ struct e1000_ffvt_entry { #define E1000_82542_FFMT E1000_FFMT #define E1000_82542_FFVT E1000_FFVT #define E1000_82542_HOST_IF E1000_HOST_IF +#define E1000_82542_IAM E1000_IAM +#define E1000_82542_EEMNGCTL E1000_EEMNGCTL +#define E1000_82542_PSRCTL E1000_PSRCTL +#define E1000_82542_RAID E1000_RAID +#define E1000_82542_TARC0 E1000_TARC0 +#define E1000_82542_TDBAL1 E1000_TDBAL1 +#define E1000_82542_TDBAH1 E1000_TDBAH1 +#define E1000_82542_TDLEN1 E1000_TDLEN1 +#define E1000_82542_TDH1 E1000_TDH1 +#define E1000_82542_TDT1 E1000_TDT1 +#define E1000_82542_TXDCTL1 E1000_TXDCTL1 +#define E1000_82542_TARC1 E1000_TARC1 +#define E1000_82542_RFCTL E1000_RFCTL +#define E1000_82542_GCR E1000_GCR +#define E1000_82542_GSCL_1 E1000_GSCL_1 +#define E1000_82542_GSCL_2 E1000_GSCL_2 +#define E1000_82542_GSCL_3 E1000_GSCL_3 +#define E1000_82542_GSCL_4 E1000_GSCL_4 +#define E1000_82542_FACTPS E1000_FACTPS +#define E1000_82542_SWSM E1000_SWSM +#define E1000_82542_FWSM E1000_FWSM +#define E1000_82542_FFLT_DBG E1000_FFLT_DBG +#define E1000_82542_IAC E1000_IAC +#define E1000_82542_ICRXPTC E1000_ICRXPTC +#define E1000_82542_ICRXATC E1000_ICRXATC +#define E1000_82542_ICTXPTC E1000_ICTXPTC +#define E1000_82542_ICTXATC E1000_ICTXATC +#define E1000_82542_ICTXQEC E1000_ICTXQEC +#define E1000_82542_ICTXQMTC E1000_ICTXQMTC +#define E1000_82542_ICRXDMTC E1000_ICRXDMTC +#define E1000_82542_ICRXOC E1000_ICRXOC +#define E1000_82542_HICR E1000_HICR /* Statistics counters collected by the MAC */ struct e1000_hw_stats { @@ -974,11 +1256,21 @@ struct e1000_hw_stats { uint64_t bptc; uint64_t tsctc; uint64_t tsctfc; + uint64_t iac; + uint64_t icrxptc; + uint64_t icrxatc; + uint64_t ictxptc; + uint64_t ictxatc; + uint64_t ictxqec; + uint64_t ictxqmtc; + uint64_t icrxdmtc; + uint64_t icrxoc; }; /* Structure containing variables used by the shared code (e1000_hw.c) */ struct e1000_hw { - uint8_t __iomem *hw_addr; + uint8_t *hw_addr; + uint8_t *flash_address; e1000_mac_type mac_type; e1000_phy_type phy_type; uint32_t phy_init_script; @@ -993,6 +1285,7 @@ struct e1000_hw { e1000_ms_type original_master_slave; e1000_ffe_config ffe_config_state; uint32_t asf_firmware_present; + uint32_t eeprom_semaphore_present; unsigned long io_base; uint32_t phy_id; uint32_t phy_revision; @@ -1009,6 +1302,8 @@ struct e1000_hw { uint32_t ledctl_default; uint32_t ledctl_mode1; uint32_t ledctl_mode2; + boolean_t tx_pkt_filtering; + struct e1000_host_mng_dhcp_cookie mng_cookie; uint16_t phy_spd_default; uint16_t autoneg_advertised; uint16_t pci_cmd_word; @@ -1047,16 +1342,24 @@ struct e1000_hw { boolean_t adaptive_ifs; boolean_t ifs_params_forced; boolean_t in_ifs_mode; + boolean_t mng_reg_access_disabled; }; #define E1000_EEPROM_SWDPIN0 0x0001 /* SWDPIN 0 EEPROM Value */ #define E1000_EEPROM_LED_LOGIC 0x0020 /* Led Logic Word */ +#define E1000_EEPROM_RW_REG_DATA 16 /* Offset to data in EEPROM read/write registers */ +#define E1000_EEPROM_RW_REG_DONE 2 /* Offset to READ/WRITE done bit */ +#define E1000_EEPROM_RW_REG_START 1 /* First bit for telling part to start operation */ +#define E1000_EEPROM_RW_ADDR_SHIFT 2 /* Shift to the address bits */ +#define E1000_EEPROM_POLL_WRITE 1 /* Flag for polling for write complete */ +#define E1000_EEPROM_POLL_READ 0 /* Flag for polling for read complete */ /* Register Bit Masks */ /* Device Control */ #define E1000_CTRL_FD 0x00000001 /* Full duplex.0=half; 1=full */ #define E1000_CTRL_BEM 0x00000002 /* Endian Mode.0=little,1=big */ #define E1000_CTRL_PRIOR 0x00000004 /* Priority on PCI. 0=rx,1=fair */ +#define E1000_CTRL_GIO_MASTER_DISABLE 0x00000004 /*Blocks new Master requests */ #define E1000_CTRL_LRST 0x00000008 /* Link reset. 0=normal,1=reset */ #define E1000_CTRL_TME 0x00000010 /* Test mode. 0=normal,1=test */ #define E1000_CTRL_SLE 0x00000020 /* Serial Link on 0=dis,1=en */ @@ -1070,6 +1373,7 @@ struct e1000_hw { #define E1000_CTRL_BEM32 0x00000400 /* Big Endian 32 mode */ #define E1000_CTRL_FRCSPD 0x00000800 /* Force Speed */ #define E1000_CTRL_FRCDPX 0x00001000 /* Force Duplex */ +#define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */ #define E1000_CTRL_SWDPIN0 0x00040000 /* SWDPIN 0 value */ #define E1000_CTRL_SWDPIN1 0x00080000 /* SWDPIN 1 value */ #define E1000_CTRL_SWDPIN2 0x00100000 /* SWDPIN 2 value */ @@ -1089,6 +1393,7 @@ struct e1000_hw { #define E1000_STATUS_FD 0x00000001 /* Full duplex.0=half,1=full */ #define E1000_STATUS_LU 0x00000002 /* Link up.0=no,1=link */ #define E1000_STATUS_FUNC_MASK 0x0000000C /* PCI Function Mask */ +#define E1000_STATUS_FUNC_SHIFT 2 #define E1000_STATUS_FUNC_0 0x00000000 /* Function 0 */ #define E1000_STATUS_FUNC_1 0x00000004 /* Function 1 */ #define E1000_STATUS_TXOFF 0x00000010 /* transmission paused */ @@ -1098,6 +1403,8 @@ struct e1000_hw { #define E1000_STATUS_SPEED_100 0x00000040 /* Speed 100Mb/s */ #define E1000_STATUS_SPEED_1000 0x00000080 /* Speed 1000Mb/s */ #define E1000_STATUS_ASDV 0x00000300 /* Auto speed detect value */ +#define E1000_STATUS_DOCK_CI 0x00000800 /* Change in Dock/Undock state. Clear on write '0'. */ +#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000 /* Status of Master requests. */ #define E1000_STATUS_MTXCKOK 0x00000400 /* MTX clock running OK */ #define E1000_STATUS_PCI66 0x00000800 /* In 66Mhz slot */ #define E1000_STATUS_BUS64 0x00001000 /* In 64 bit slot */ @@ -1128,6 +1435,18 @@ struct e1000_hw { #ifndef E1000_EEPROM_GRANT_ATTEMPTS #define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */ #endif +#define E1000_EECD_AUTO_RD 0x00000200 /* EEPROM Auto Read done */ +#define E1000_EECD_SIZE_EX_MASK 0x00007800 /* EEprom Size */ +#define E1000_EECD_SIZE_EX_SHIFT 11 +#define E1000_EECD_NVADDS 0x00018000 /* NVM Address Size */ +#define E1000_EECD_SELSHAD 0x00020000 /* Select Shadow RAM */ +#define E1000_EECD_INITSRAM 0x00040000 /* Initialize Shadow RAM */ +#define E1000_EECD_FLUPD 0x00080000 /* Update FLASH */ +#define E1000_EECD_AUPDEN 0x00100000 /* Enable Autonomous FLASH update */ +#define E1000_EECD_SHADV 0x00200000 /* Shadow RAM Data Valid */ +#define E1000_EECD_SEC1VAL 0x00400000 /* Sector One Valid */ +#define E1000_STM_OPCODE 0xDB00 +#define E1000_HICR_FW_RESET 0xC0 /* EEPROM Read */ #define E1000_EERD_START 0x00000001 /* Start Read */ @@ -1171,6 +1490,8 @@ struct e1000_hw { #define E1000_CTRL_EXT_WR_WMARK_320 0x01000000 #define E1000_CTRL_EXT_WR_WMARK_384 0x02000000 #define E1000_CTRL_EXT_WR_WMARK_448 0x03000000 +#define E1000_CTRL_EXT_IAME 0x08000000 /* Interrupt acknowledge Auto-mask */ +#define E1000_CTRL_EXT_INT_TIMER_CLR 0x20000000 /* Clear Interrupt timers after IMS clear */ /* MDI Control */ #define E1000_MDIC_DATA_MASK 0x0000FFFF @@ -1187,14 +1508,17 @@ struct e1000_hw { /* LED Control */ #define E1000_LEDCTL_LED0_MODE_MASK 0x0000000F #define E1000_LEDCTL_LED0_MODE_SHIFT 0 +#define E1000_LEDCTL_LED0_BLINK_RATE 0x0000020 #define E1000_LEDCTL_LED0_IVRT 0x00000040 #define E1000_LEDCTL_LED0_BLINK 0x00000080 #define E1000_LEDCTL_LED1_MODE_MASK 0x00000F00 #define E1000_LEDCTL_LED1_MODE_SHIFT 8 +#define E1000_LEDCTL_LED1_BLINK_RATE 0x0002000 #define E1000_LEDCTL_LED1_IVRT 0x00004000 #define E1000_LEDCTL_LED1_BLINK 0x00008000 #define E1000_LEDCTL_LED2_MODE_MASK 0x000F0000 #define E1000_LEDCTL_LED2_MODE_SHIFT 16 +#define E1000_LEDCTL_LED2_BLINK_RATE 0x00200000 #define E1000_LEDCTL_LED2_IVRT 0x00400000 #define E1000_LEDCTL_LED2_BLINK 0x00800000 #define E1000_LEDCTL_LED3_MODE_MASK 0x0F000000 @@ -1238,6 +1562,10 @@ struct e1000_hw { #define E1000_ICR_GPI_EN3 0x00004000 /* GP Int 3 */ #define E1000_ICR_TXD_LOW 0x00008000 #define E1000_ICR_SRPD 0x00010000 +#define E1000_ICR_ACK 0x00020000 /* Receive Ack frame */ +#define E1000_ICR_MNG 0x00040000 /* Manageability event */ +#define E1000_ICR_DOCK 0x00080000 /* Dock/Undock */ +#define E1000_ICR_INT_ASSERTED 0x80000000 /* If this bit asserted, the driver should claim the interrupt */ /* Interrupt Cause Set */ #define E1000_ICS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1255,6 +1583,9 @@ struct e1000_hw { #define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW #define E1000_ICS_SRPD E1000_ICR_SRPD +#define E1000_ICS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_ICS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_ICS_DOCK E1000_ICR_DOCK /* Dock/Undock */ /* Interrupt Mask Set */ #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1272,6 +1603,9 @@ struct e1000_hw { #define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW #define E1000_IMS_SRPD E1000_ICR_SRPD +#define E1000_IMS_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMS_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMS_DOCK E1000_ICR_DOCK /* Dock/Undock */ /* Interrupt Mask Clear */ #define E1000_IMC_TXDW E1000_ICR_TXDW /* Transmit desc written back */ @@ -1289,6 +1623,9 @@ struct e1000_hw { #define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3 /* GP Int 3 */ #define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW #define E1000_IMC_SRPD E1000_ICR_SRPD +#define E1000_IMC_ACK E1000_ICR_ACK /* Receive Ack frame */ +#define E1000_IMC_MNG E1000_ICR_MNG /* Manageability event */ +#define E1000_IMC_DOCK E1000_ICR_DOCK /* Dock/Undock */ /* Receive Control */ #define E1000_RCTL_RST 0x00000001 /* Software reset */ @@ -1301,6 +1638,8 @@ struct e1000_hw { #define E1000_RCTL_LBM_MAC 0x00000040 /* MAC loopback mode */ #define E1000_RCTL_LBM_SLP 0x00000080 /* serial link loopback mode */ #define E1000_RCTL_LBM_TCVR 0x000000C0 /* tcvr loopback mode */ +#define E1000_RCTL_DTYP_MASK 0x00000C00 /* Descriptor type mask */ +#define E1000_RCTL_DTYP_PS 0x00000400 /* Packet Split descriptor */ #define E1000_RCTL_RDMTS_HALF 0x00000000 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_QUAT 0x00000100 /* rx desc min threshold size */ #define E1000_RCTL_RDMTS_EIGTH 0x00000200 /* rx desc min threshold size */ @@ -1327,6 +1666,34 @@ struct e1000_hw { #define E1000_RCTL_PMCF 0x00800000 /* pass MAC control frames */ #define E1000_RCTL_BSEX 0x02000000 /* Buffer size extension */ #define E1000_RCTL_SECRC 0x04000000 /* Strip Ethernet CRC */ +#define E1000_RCTL_FLXBUF_MASK 0x78000000 /* Flexible buffer size */ +#define E1000_RCTL_FLXBUF_SHIFT 27 /* Flexible buffer shift */ + +/* Use byte values for the following shift parameters + * Usage: + * psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) & + * E1000_PSRCTL_BSIZE0_MASK) | + * ((ROUNDUP(value1, 1024) >> E1000_PSRCTL_BSIZE1_SHIFT) & + * E1000_PSRCTL_BSIZE1_MASK) | + * ((ROUNDUP(value2, 1024) << E1000_PSRCTL_BSIZE2_SHIFT) & + * E1000_PSRCTL_BSIZE2_MASK) | + * ((ROUNDUP(value3, 1024) << E1000_PSRCTL_BSIZE3_SHIFT) |; + * E1000_PSRCTL_BSIZE3_MASK)) + * where value0 = [128..16256], default=256 + * value1 = [1024..64512], default=4096 + * value2 = [0..64512], default=4096 + * value3 = [0..64512], default=0 + */ + +#define E1000_PSRCTL_BSIZE0_MASK 0x0000007F +#define E1000_PSRCTL_BSIZE1_MASK 0x00003F00 +#define E1000_PSRCTL_BSIZE2_MASK 0x003F0000 +#define E1000_PSRCTL_BSIZE3_MASK 0x3F000000 + +#define E1000_PSRCTL_BSIZE0_SHIFT 7 /* Shift _right_ 7 */ +#define E1000_PSRCTL_BSIZE1_SHIFT 2 /* Shift _right_ 2 */ +#define E1000_PSRCTL_BSIZE2_SHIFT 6 /* Shift _left_ 6 */ +#define E1000_PSRCTL_BSIZE3_SHIFT 14 /* Shift _left_ 14 */ /* Receive Descriptor */ #define E1000_RDT_DELAY 0x0000ffff /* Delay timer (1=1024us) */ @@ -1341,6 +1708,23 @@ struct e1000_hw { #define E1000_FCRTL_RTL 0x0000FFF8 /* Mask Bits[15:3] for RTL */ #define E1000_FCRTL_XONE 0x80000000 /* Enable XON frame transmission */ +/* Header split receive */ +#define E1000_RFCTL_ISCSI_DIS 0x00000001 +#define E1000_RFCTL_ISCSI_DWC_MASK 0x0000003E +#define E1000_RFCTL_ISCSI_DWC_SHIFT 1 +#define E1000_RFCTL_NFSW_DIS 0x00000040 +#define E1000_RFCTL_NFSR_DIS 0x00000080 +#define E1000_RFCTL_NFS_VER_MASK 0x00000300 +#define E1000_RFCTL_NFS_VER_SHIFT 8 +#define E1000_RFCTL_IPV6_DIS 0x00000400 +#define E1000_RFCTL_IPV6_XSUM_DIS 0x00000800 +#define E1000_RFCTL_ACK_DIS 0x00001000 +#define E1000_RFCTL_ACKD_DIS 0x00002000 +#define E1000_RFCTL_IPFRSP_DIS 0x00004000 +#define E1000_RFCTL_EXTEN 0x00008000 +#define E1000_RFCTL_IPV6_EX_DIS 0x00010000 +#define E1000_RFCTL_NEW_IPV6_EXT_DIS 0x00020000 + /* Receive Descriptor Control */ #define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */ #define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */ @@ -1354,6 +1738,8 @@ struct e1000_hw { #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ +#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc. + still to be processed. */ /* Transmit Configuration Word */ #define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ @@ -1387,12 +1773,16 @@ struct e1000_hw { #define E1000_TCTL_PBE 0x00800000 /* Packet Burst Enable */ #define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */ #define E1000_TCTL_NRTU 0x02000000 /* No Re-transmit on underrun */ +#define E1000_TCTL_MULR 0x10000000 /* Multiple request support */ /* Receive Checksum Control */ #define E1000_RXCSUM_PCSS_MASK 0x000000FF /* Packet Checksum Start */ #define E1000_RXCSUM_IPOFL 0x00000100 /* IPv4 checksum offload */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ #define E1000_RXCSUM_IPV6OFL 0x00000400 /* IPv6 checksum offload */ +#define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ +#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ + /* Definitions for power management and wakeup registers */ /* Wake Up Control */ @@ -1411,6 +1801,7 @@ struct e1000_hw { #define E1000_WUFC_ARP 0x00000020 /* ARP Request Packet Wakeup Enable */ #define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */ #define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */ +#define E1000_WUFC_IGNORE_TCO 0x00008000 /* Ignore WakeOn TCO packets */ #define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */ #define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */ #define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */ @@ -1446,13 +1837,19 @@ struct e1000_hw { #define E1000_MANC_ARP_EN 0x00002000 /* Enable ARP Request Filtering */ #define E1000_MANC_NEIGHBOR_EN 0x00004000 /* Enable Neighbor Discovery * Filtering */ +#define E1000_MANC_ARP_RES_EN 0x00008000 /* Enable ARP response Filtering */ #define E1000_MANC_TCO_RESET 0x00010000 /* TCO Reset Occurred */ #define E1000_MANC_RCV_TCO_EN 0x00020000 /* Receive TCO Packets Enabled */ #define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */ +#define E1000_MANC_BLK_PHY_RST_ON_IDE 0x00040000 /* Block phy resets */ #define E1000_MANC_EN_MAC_ADDR_FILTER 0x00100000 /* Enable MAC address * filtering */ #define E1000_MANC_EN_MNG2HOST 0x00200000 /* Enable MNG packets to host * memory */ +#define E1000_MANC_EN_IP_ADDR_FILTER 0x00400000 /* Enable IP address + * filtering */ +#define E1000_MANC_EN_XSUM_FILTER 0x00800000 /* Enable checksum filtering */ +#define E1000_MANC_BR_EN 0x01000000 /* Enable broadcast filtering */ #define E1000_MANC_SMB_REQ 0x01000000 /* SMBus Request */ #define E1000_MANC_SMB_GNT 0x02000000 /* SMBus Grant */ #define E1000_MANC_SMB_CLK_IN 0x04000000 /* SMBus Clock In */ @@ -1463,11 +1860,97 @@ struct e1000_hw { #define E1000_MANC_SMB_DATA_OUT_SHIFT 28 /* SMBus Data Out Shift */ #define E1000_MANC_SMB_CLK_OUT_SHIFT 29 /* SMBus Clock Out Shift */ +/* SW Semaphore Register */ +#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */ +#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */ +#define E1000_SWSM_WMNG 0x00000004 /* Wake MNG Clock */ +#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */ + +/* FW Semaphore Register */ +#define E1000_FWSM_MODE_MASK 0x0000000E /* FW mode */ +#define E1000_FWSM_MODE_SHIFT 1 +#define E1000_FWSM_FW_VALID 0x00008000 /* FW established a valid mode */ + +/* FFLT Debug Register */ +#define E1000_FFLT_DBG_INVC 0x00100000 /* Invalid /C/ code handling */ + +typedef enum { + e1000_mng_mode_none = 0, + e1000_mng_mode_asf, + e1000_mng_mode_pt, + e1000_mng_mode_ipmi, + e1000_mng_mode_host_interface_only +} e1000_mng_mode; + +/* Host Inteface Control Register */ +#define E1000_HICR_EN 0x00000001 /* Enable Bit - RO */ +#define E1000_HICR_C 0x00000002 /* Driver sets this bit when done + * to put command in RAM */ +#define E1000_HICR_SV 0x00000004 /* Status Validity */ +#define E1000_HICR_FWR 0x00000080 /* FW reset. Set by the Host */ + +/* Host Interface Command Interface - Address range 0x8800-0x8EFF */ +#define E1000_HI_MAX_DATA_LENGTH 252 /* Host Interface data length */ +#define E1000_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Number of bytes in range */ +#define E1000_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Number of dwords in range */ +#define E1000_HI_COMMAND_TIMEOUT 500 /* Time in ms to process HI command */ + +struct e1000_host_command_header { + uint8_t command_id; + uint8_t command_length; + uint8_t command_options; /* I/F bits for command, status for return */ + uint8_t checksum; +}; +struct e1000_host_command_info { + struct e1000_host_command_header command_header; /* Command Head/Command Result Head has 4 bytes */ + uint8_t command_data[E1000_HI_MAX_DATA_LENGTH]; /* Command data can length 0..252 */ +}; + +/* Host SMB register #0 */ +#define E1000_HSMC0R_CLKIN 0x00000001 /* SMB Clock in */ +#define E1000_HSMC0R_DATAIN 0x00000002 /* SMB Data in */ +#define E1000_HSMC0R_DATAOUT 0x00000004 /* SMB Data out */ +#define E1000_HSMC0R_CLKOUT 0x00000008 /* SMB Clock out */ + +/* Host SMB register #1 */ +#define E1000_HSMC1R_CLKIN E1000_HSMC0R_CLKIN +#define E1000_HSMC1R_DATAIN E1000_HSMC0R_DATAIN +#define E1000_HSMC1R_DATAOUT E1000_HSMC0R_DATAOUT +#define E1000_HSMC1R_CLKOUT E1000_HSMC0R_CLKOUT + +/* FW Status Register */ +#define E1000_FWSTS_FWS_MASK 0x000000FF /* FW Status */ + /* Wake Up Packet Length */ #define E1000_WUPL_LENGTH_MASK 0x0FFF /* Only the lower 12 bits are valid */ #define E1000_MDALIGN 4096 +#define E1000_GCR_BEM32 0x00400000 +/* Function Active and Power State to MNG */ +#define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 +#define E1000_FACTPS_LAN0_VALID 0x00000004 +#define E1000_FACTPS_FUNC0_AUX_EN 0x00000008 +#define E1000_FACTPS_FUNC1_POWER_STATE_MASK 0x000000C0 +#define E1000_FACTPS_FUNC1_POWER_STATE_SHIFT 6 +#define E1000_FACTPS_LAN1_VALID 0x00000100 +#define E1000_FACTPS_FUNC1_AUX_EN 0x00000200 +#define E1000_FACTPS_FUNC2_POWER_STATE_MASK 0x00003000 +#define E1000_FACTPS_FUNC2_POWER_STATE_SHIFT 12 +#define E1000_FACTPS_IDE_ENABLE 0x00004000 +#define E1000_FACTPS_FUNC2_AUX_EN 0x00008000 +#define E1000_FACTPS_FUNC3_POWER_STATE_MASK 0x000C0000 +#define E1000_FACTPS_FUNC3_POWER_STATE_SHIFT 18 +#define E1000_FACTPS_SP_ENABLE 0x00100000 +#define E1000_FACTPS_FUNC3_AUX_EN 0x00200000 +#define E1000_FACTPS_FUNC4_POWER_STATE_MASK 0x03000000 +#define E1000_FACTPS_FUNC4_POWER_STATE_SHIFT 24 +#define E1000_FACTPS_IPMI_ENABLE 0x04000000 +#define E1000_FACTPS_FUNC4_AUX_EN 0x08000000 +#define E1000_FACTPS_MNGCG 0x20000000 +#define E1000_FACTPS_LAN_FUNC_SEL 0x40000000 +#define E1000_FACTPS_PM_STATE_CHANGED 0x80000000 + /* EEPROM Commands - Microwire */ #define EEPROM_READ_OPCODE_MICROWIRE 0x6 /* EEPROM read opcode */ #define EEPROM_WRITE_OPCODE_MICROWIRE 0x5 /* EEPROM write opcode */ @@ -1477,22 +1960,20 @@ struct e1000_hw { /* EEPROM Commands - SPI */ #define EEPROM_MAX_RETRY_SPI 5000 /* Max wait of 5ms, for RDY signal */ -#define EEPROM_READ_OPCODE_SPI 0x3 /* EEPROM read opcode */ -#define EEPROM_WRITE_OPCODE_SPI 0x2 /* EEPROM write opcode */ -#define EEPROM_A8_OPCODE_SPI 0x8 /* opcode bit-3 = address bit-8 */ -#define EEPROM_WREN_OPCODE_SPI 0x6 /* EEPROM set Write Enable latch */ -#define EEPROM_WRDI_OPCODE_SPI 0x4 /* EEPROM reset Write Enable latch */ -#define EEPROM_RDSR_OPCODE_SPI 0x5 /* EEPROM read Status register */ -#define EEPROM_WRSR_OPCODE_SPI 0x1 /* EEPROM write Status register */ +#define EEPROM_READ_OPCODE_SPI 0x03 /* EEPROM read opcode */ +#define EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */ +#define EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = address bit-8 */ +#define EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Enable latch */ +#define EEPROM_WRDI_OPCODE_SPI 0x04 /* EEPROM reset Write Enable latch */ +#define EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status register */ +#define EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status register */ +#define EEPROM_ERASE4K_OPCODE_SPI 0x20 /* EEPROM ERASE 4KB */ +#define EEPROM_ERASE64K_OPCODE_SPI 0xD8 /* EEPROM ERASE 64KB */ +#define EEPROM_ERASE256_OPCODE_SPI 0xDB /* EEPROM ERASE 256B */ /* EEPROM Size definitions */ -#define EEPROM_SIZE_16KB 0x1800 -#define EEPROM_SIZE_8KB 0x1400 -#define EEPROM_SIZE_4KB 0x1000 -#define EEPROM_SIZE_2KB 0x0C00 -#define EEPROM_SIZE_1KB 0x0800 -#define EEPROM_SIZE_512B 0x0400 -#define EEPROM_SIZE_128B 0x0000 +#define EEPROM_WORD_SIZE_SHIFT 6 +#define EEPROM_SIZE_SHIFT 10 #define EEPROM_SIZE_MASK 0x1C00 /* EEPROM Word Offsets */ @@ -1606,7 +2087,22 @@ struct e1000_hw { #define IFS_MIN 40 #define IFS_RATIO 4 +/* Extended Configuration Control and Size */ +#define E1000_EXTCNF_CTRL_PCIE_WRITE_ENABLE 0x00000001 +#define E1000_EXTCNF_CTRL_PHY_WRITE_ENABLE 0x00000002 +#define E1000_EXTCNF_CTRL_D_UD_ENABLE 0x00000004 +#define E1000_EXTCNF_CTRL_D_UD_LATENCY 0x00000008 +#define E1000_EXTCNF_CTRL_D_UD_OWNER 0x00000010 +#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020 +#define E1000_EXTCNF_CTRL_MDIO_HW_OWNERSHIP 0x00000040 +#define E1000_EXTCNF_CTRL_EXT_CNF_POINTER 0x1FFF0000 + +#define E1000_EXTCNF_SIZE_EXT_PHY_LENGTH 0x000000FF +#define E1000_EXTCNF_SIZE_EXT_DOCK_LENGTH 0x0000FF00 +#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH 0x00FF0000 + /* PBA constants */ +#define E1000_PBA_12K 0x000C /* 12KB, default Rx allocation */ #define E1000_PBA_16K 0x0010 /* 16KB, default TX allocation */ #define E1000_PBA_22K 0x0016 #define E1000_PBA_24K 0x0018 @@ -1663,6 +2159,13 @@ struct e1000_hw { /* Number of milliseconds we wait for auto-negotiation to complete */ #define LINK_UP_TIMEOUT 500 +/* Number of 100 microseconds we wait for PCI Express master disable */ +#define MASTER_DISABLE_TIMEOUT 800 +/* Number of milliseconds we wait for Eeprom auto read bit done after MAC reset */ +#define AUTO_READ_DONE_TIMEOUT 10 +/* Number of milliseconds we wait for PHY configuration done after MAC reset */ +#define PHY_CFG_TIMEOUT 40 + #define E1000_TX_BUFFER_SIZE ((uint32_t)1514) /* The carrier extension symbol, as received by the NIC. */ @@ -1763,6 +2266,7 @@ struct e1000_hw { #define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */ #define IGP01E1000_GMII_FIFO 0x14 /* GMII FIFO Register */ #define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */ +#define IGP02E1000_PHY_POWER_MGMT 0x19 #define IGP01E1000_PHY_PAGE_SELECT 0x1F /* PHY Page Select Core Register */ /* IGP01E1000 AGC Registers - stores the cable length values*/ @@ -1771,12 +2275,20 @@ struct e1000_hw { #define IGP01E1000_PHY_AGC_C 0x1472 #define IGP01E1000_PHY_AGC_D 0x1872 +/* IGP02E1000 AGC Registers for cable length values */ +#define IGP02E1000_PHY_AGC_A 0x11B1 +#define IGP02E1000_PHY_AGC_B 0x12B1 +#define IGP02E1000_PHY_AGC_C 0x14B1 +#define IGP02E1000_PHY_AGC_D 0x18B1 + /* IGP01E1000 DSP Reset Register */ #define IGP01E1000_PHY_DSP_RESET 0x1F33 #define IGP01E1000_PHY_DSP_SET 0x1F71 #define IGP01E1000_PHY_DSP_FFE 0x1F35 #define IGP01E1000_PHY_CHANNEL_NUM 4 +#define IGP02E1000_PHY_CHANNEL_NUM 4 + #define IGP01E1000_PHY_AGC_PARAM_A 0x1171 #define IGP01E1000_PHY_AGC_PARAM_B 0x1271 #define IGP01E1000_PHY_AGC_PARAM_C 0x1471 @@ -2060,20 +2572,30 @@ struct e1000_hw { #define IGP01E1000_MSE_CHANNEL_B 0x0F00 #define IGP01E1000_MSE_CHANNEL_A 0xF000 +#define IGP02E1000_PM_SPD 0x0001 /* Smart Power Down */ +#define IGP02E1000_PM_D3_LPLU 0x0004 /* Enable LPLU in non-D0a modes */ +#define IGP02E1000_PM_D0_LPLU 0x0002 /* Enable LPLU in D0a mode */ + /* IGP01E1000 DSP reset macros */ #define DSP_RESET_ENABLE 0x0 #define DSP_RESET_DISABLE 0x2 #define E1000_MAX_DSP_RESETS 10 -/* IGP01E1000 AGC Registers */ +/* IGP01E1000 & IGP02E1000 AGC Registers */ #define IGP01E1000_AGC_LENGTH_SHIFT 7 /* Coarse - 13:11, Fine - 10:7 */ +#define IGP02E1000_AGC_LENGTH_SHIFT 9 /* Coarse - 15:13, Fine - 12:9 */ + +/* IGP02E1000 AGC Register Length 9-bit mask */ +#define IGP02E1000_AGC_LENGTH_MASK 0x7F /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */ #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128 +#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128 -/* The precision of the length is +/- 10 meters */ +/* The precision error of the cable length is +/- 10 meters */ #define IGP01E1000_AGC_RANGE 10 +#define IGP02E1000_AGC_RANGE 10 /* IGP01E1000 PCS Initialization register */ /* bits 3:6 in the PCS registers stores the channels polarity */ @@ -2113,6 +2635,8 @@ struct e1000_hw { #define M88E1000_12_PHY_ID M88E1000_E_PHY_ID #define M88E1000_14_PHY_ID M88E1000_E_PHY_ID #define M88E1011_I_REV_4 0x04 +#define M88E1111_I_PHY_ID 0x01410CC0 +#define L1LXT971A_PHY_ID 0x001378E0 /* Miscellaneous PHY bit definitions. */ #define PHY_PREAMBLE 0xFFFFFFFF diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4cdf371961eb..5e6e1f7fd777 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -155,10 +155,14 @@ static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter); static int e1000_clean(struct net_device *netdev, int *budget); static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done, int work_to_do); +static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, + int *work_done, int work_to_do); #else static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter); +static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter); #endif static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter); +static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter); 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); @@ -286,7 +290,29 @@ e1000_irq_enable(struct e1000_adapter *adapter) E1000_WRITE_FLUSH(&adapter->hw); } } - +void +e1000_update_mng_vlan(struct e1000_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + uint16_t vid = adapter->hw.mng_cookie.vlan_id; + uint16_t old_vid = adapter->mng_vlan_id; + if(adapter->vlgrp) { + if(!adapter->vlgrp->vlan_devices[vid]) { + if(adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) { + e1000_vlan_rx_add_vid(netdev, vid); + adapter->mng_vlan_id = vid; + } else + adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; + + if((old_vid != (uint16_t)E1000_MNG_VLAN_NONE) && + (vid != old_vid) && + !adapter->vlgrp->vlan_devices[old_vid]) + e1000_vlan_rx_kill_vid(netdev, old_vid); + } + } +} + int e1000_up(struct e1000_adapter *adapter) { @@ -310,7 +336,7 @@ e1000_up(struct e1000_adapter *adapter) e1000_configure_tx(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - e1000_alloc_rx_buffers(adapter); + adapter->alloc_rx_buf(adapter); #ifdef CONFIG_PCI_MSI if(adapter->hw.mac_type > e1000_82547_rev_2) { @@ -366,8 +392,12 @@ e1000_down(struct e1000_adapter *adapter) e1000_clean_rx_ring(adapter); /* If WoL is not enabled + * and management mode is not IAMT * Power down the PHY so no link is implied when interface is down */ - if(!adapter->wol && adapter->hw.media_type == e1000_media_type_copper) { + if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 && + adapter->hw.media_type == e1000_media_type_copper && + !e1000_check_mng_mode(&adapter->hw) && + !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN)) { uint16_t mii_reg; e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; @@ -379,28 +409,34 @@ e1000_down(struct e1000_adapter *adapter) void e1000_reset(struct e1000_adapter *adapter) { - uint32_t pba; + uint32_t pba, manc; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. */ - if(adapter->hw.mac_type < e1000_82547) { - if(adapter->rx_buffer_len > E1000_RXBUFFER_8192) - pba = E1000_PBA_40K; - else - pba = E1000_PBA_48K; - } else { - if(adapter->rx_buffer_len > E1000_RXBUFFER_8192) - pba = E1000_PBA_22K; - else - pba = E1000_PBA_30K; + switch (adapter->hw.mac_type) { + case e1000_82547: + pba = E1000_PBA_30K; + break; + case e1000_82573: + pba = E1000_PBA_12K; + break; + default: + pba = E1000_PBA_48K; + break; + } + + + + if(adapter->hw.mac_type == e1000_82547) { adapter->tx_fifo_head = 0; adapter->tx_head_addr = pba << E1000_TX_HEAD_ADDR_SHIFT; adapter->tx_fifo_size = (E1000_PBA_40K - pba) << E1000_PBA_BYTES_SHIFT; atomic_set(&adapter->tx_fifo_stall, 0); } + E1000_WRITE_REG(&adapter->hw, PBA, pba); /* flow control settings */ @@ -412,17 +448,23 @@ e1000_reset(struct e1000_adapter *adapter) adapter->hw.fc_send_xon = 1; adapter->hw.fc = adapter->hw.original_fc; + /* Allow time for pending master requests to run */ e1000_reset_hw(&adapter->hw); if(adapter->hw.mac_type >= e1000_82544) E1000_WRITE_REG(&adapter->hw, WUC, 0); if(e1000_init_hw(&adapter->hw)) DPRINTK(PROBE, ERR, "Hardware Error\n"); - + e1000_update_mng_vlan(adapter); /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE); e1000_reset_adaptive(&adapter->hw); e1000_phy_get_info(&adapter->hw, &adapter->phy_info); + if (adapter->en_mng_pt) { + manc = E1000_READ_REG(&adapter->hw, MANC); + manc |= (E1000_MANC_ARP_EN | E1000_MANC_EN_MNG2HOST); + E1000_WRITE_REG(&adapter->hw, MANC, manc); + } } /** @@ -443,15 +485,13 @@ e1000_probe(struct pci_dev *pdev, { struct net_device *netdev; struct e1000_adapter *adapter; + unsigned long mmio_start, mmio_len; + uint32_t swsm; + static int cards_found = 0; - unsigned long mmio_start; - int mmio_len; - int pci_using_dac; - int i; - int err; + int i, err, pci_using_dac; uint16_t eeprom_data; uint16_t eeprom_apme_mask = E1000_EEPROM_APME; - if((err = pci_enable_device(pdev))) return err; @@ -538,6 +578,9 @@ e1000_probe(struct pci_dev *pdev, if((err = e1000_sw_init(adapter))) goto err_sw_init; + if((err = e1000_check_phy_reset_block(&adapter->hw))) + DPRINTK(PROBE, INFO, "PHY reset is blocked due to SOL/IDER session.\n"); + if(adapter->hw.mac_type >= e1000_82543) { netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | @@ -550,6 +593,11 @@ e1000_probe(struct pci_dev *pdev, if((adapter->hw.mac_type >= e1000_82544) && (adapter->hw.mac_type != e1000_82547)) netdev->features |= NETIF_F_TSO; + +#ifdef NETIF_F_TSO_IPV6 + if(adapter->hw.mac_type > e1000_82547_rev_2) + netdev->features |= NETIF_F_TSO_IPV6; +#endif #endif if(pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; @@ -557,6 +605,8 @@ e1000_probe(struct pci_dev *pdev, /* hard_start_xmit is safe against parallel locking */ netdev->features |= NETIF_F_LLTX; + adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw); + /* before reading the EEPROM, reset the controller to * put the device in a known good starting state */ @@ -646,6 +696,17 @@ e1000_probe(struct pci_dev *pdev, /* reset the hardware with the new settings */ e1000_reset(adapter); + /* Let firmware know the driver has taken over */ + switch(adapter->hw.mac_type) { + case e1000_82573: + swsm = E1000_READ_REG(&adapter->hw, SWSM); + E1000_WRITE_REG(&adapter->hw, SWSM, + swsm | E1000_SWSM_DRV_LOAD); + break; + default: + break; + } + strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) goto err_register; @@ -681,7 +742,7 @@ e1000_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - uint32_t manc; + uint32_t manc, swsm; flush_scheduled_work(); @@ -694,9 +755,21 @@ e1000_remove(struct pci_dev *pdev) } } + switch(adapter->hw.mac_type) { + case e1000_82573: + swsm = E1000_READ_REG(&adapter->hw, SWSM); + E1000_WRITE_REG(&adapter->hw, SWSM, + swsm & ~E1000_SWSM_DRV_LOAD); + break; + + default: + break; + } + unregister_netdev(netdev); - e1000_phy_hw_reset(&adapter->hw); + if(!e1000_check_phy_reset_block(&adapter->hw)) + e1000_phy_hw_reset(&adapter->hw); iounmap(adapter->hw.hw_addr); pci_release_regions(pdev); @@ -734,6 +807,7 @@ e1000_sw_init(struct e1000_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); adapter->rx_buffer_len = E1000_RXBUFFER_2048; + adapter->rx_ps_bsize0 = E1000_RXBUFFER_256; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; @@ -747,7 +821,10 @@ e1000_sw_init(struct e1000_adapter *adapter) /* initialize eeprom parameters */ - e1000_init_eeprom_params(hw); + if(e1000_init_eeprom_params(hw)) { + E1000_ERR("EEPROM initialization failed\n"); + return -EIO; + } switch(hw->mac_type) { default: @@ -812,6 +889,11 @@ e1000_open(struct net_device *netdev) if((err = e1000_up(adapter))) goto err_up; + adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; + if((adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) { + e1000_update_mng_vlan(adapter); + } return E1000_SUCCESS; @@ -847,14 +929,18 @@ e1000_close(struct net_device *netdev) e1000_free_tx_resources(adapter); e1000_free_rx_resources(adapter); + if((adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) { + e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); + } return 0; } /** * e1000_check_64k_bound - check that memory doesn't cross 64kB boundary * @adapter: address of board private structure - * @begin: address of beginning of memory - * @end: address of end of memory + * @start: address of beginning of memory + * @len: length of memory **/ static inline boolean_t e1000_check_64k_bound(struct e1000_adapter *adapter, @@ -1039,7 +1125,7 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter) { struct e1000_desc_ring *rxdr = &adapter->rx_ring; struct pci_dev *pdev = adapter->pdev; - int size; + int size, desc_len; size = sizeof(struct e1000_buffer) * rxdr->count; rxdr->buffer_info = vmalloc(size); @@ -1050,9 +1136,35 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter) } memset(rxdr->buffer_info, 0, size); + size = sizeof(struct e1000_ps_page) * rxdr->count; + rxdr->ps_page = kmalloc(size, 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; + } + memset(rxdr->ps_page, 0, size); + + size = sizeof(struct e1000_ps_page_dma) * rxdr->count; + rxdr->ps_page_dma = kmalloc(size, 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; + } + memset(rxdr->ps_page_dma, 0, size); + + if(adapter->hw.mac_type <= e1000_82547_rev_2) + desc_len = sizeof(struct e1000_rx_desc); + else + desc_len = sizeof(union e1000_rx_desc_packet_split); + /* Round up to nearest 4K */ - rxdr->size = rxdr->count * sizeof(struct e1000_rx_desc); + rxdr->size = rxdr->count * desc_len; E1000_ROUNDUP(rxdr->size, 4096); rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); @@ -1062,6 +1174,8 @@ setup_rx_desc_die: DPRINTK(PROBE, ERR, "Unble to Allocate Memory for the Recieve descriptor ring\n"); vfree(rxdr->buffer_info); + kfree(rxdr->ps_page); + kfree(rxdr->ps_page_dma); return -ENOMEM; } @@ -1089,6 +1203,8 @@ setup_rx_desc_die: "Unable to Allocate aligned Memory for the" " Receive descriptor ring\n"); vfree(rxdr->buffer_info); + kfree(rxdr->ps_page); + kfree(rxdr->ps_page_dma); return -ENOMEM; } else { /* free old, move on with the new one since its okay */ @@ -1111,7 +1227,8 @@ setup_rx_desc_die: static void e1000_setup_rctl(struct e1000_adapter *adapter) { - uint32_t rctl; + uint32_t rctl, rfctl; + uint32_t psrctl = 0; rctl = E1000_READ_REG(&adapter->hw, RCTL); @@ -1126,24 +1243,69 @@ e1000_setup_rctl(struct e1000_adapter *adapter) else rctl &= ~E1000_RCTL_SBP; + if (adapter->netdev->mtu <= ETH_DATA_LEN) + rctl &= ~E1000_RCTL_LPE; + else + rctl |= E1000_RCTL_LPE; + /* Setup buffer sizes */ - rctl &= ~(E1000_RCTL_SZ_4096); - rctl |= (E1000_RCTL_BSEX | E1000_RCTL_LPE); - switch (adapter->rx_buffer_len) { - case E1000_RXBUFFER_2048: - default: - rctl |= E1000_RCTL_SZ_2048; - rctl &= ~(E1000_RCTL_BSEX | E1000_RCTL_LPE); - break; - case E1000_RXBUFFER_4096: - rctl |= E1000_RCTL_SZ_4096; - break; - case E1000_RXBUFFER_8192: - rctl |= E1000_RCTL_SZ_8192; - break; - case E1000_RXBUFFER_16384: - rctl |= E1000_RCTL_SZ_16384; - break; + if(adapter->hw.mac_type == e1000_82573) { + /* We can now specify buffers in 1K increments. + * BSIZE and BSEX are ignored in this case. */ + rctl |= adapter->rx_buffer_len << 0x11; + } else { + rctl &= ~E1000_RCTL_SZ_4096; + rctl |= E1000_RCTL_BSEX; + switch (adapter->rx_buffer_len) { + case E1000_RXBUFFER_2048: + default: + rctl |= E1000_RCTL_SZ_2048; + rctl &= ~E1000_RCTL_BSEX; + break; + case E1000_RXBUFFER_4096: + rctl |= E1000_RCTL_SZ_4096; + break; + case E1000_RXBUFFER_8192: + rctl |= E1000_RCTL_SZ_8192; + break; + case E1000_RXBUFFER_16384: + rctl |= E1000_RCTL_SZ_16384; + break; + } + } + +#ifdef CONFIG_E1000_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. + */ + adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2) + && (adapter->netdev->mtu + < ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0)); +#endif + if(adapter->rx_ps) { + /* Configure extra packet-split registers */ + rfctl = E1000_READ_REG(&adapter->hw, RFCTL); + rfctl |= E1000_RFCTL_EXTEN; + /* disable IPv6 packet split support */ + rfctl |= E1000_RFCTL_IPV6_DIS; + E1000_WRITE_REG(&adapter->hw, RFCTL, rfctl); + + rctl |= E1000_RCTL_DTYP_PS | E1000_RCTL_SECRC; + + psrctl |= adapter->rx_ps_bsize0 >> + E1000_PSRCTL_BSIZE0_SHIFT; + psrctl |= PAGE_SIZE >> + E1000_PSRCTL_BSIZE1_SHIFT; + psrctl |= PAGE_SIZE << + E1000_PSRCTL_BSIZE2_SHIFT; + psrctl |= PAGE_SIZE << + E1000_PSRCTL_BSIZE3_SHIFT; + + E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl); } E1000_WRITE_REG(&adapter->hw, RCTL, rctl); @@ -1160,9 +1322,18 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) { uint64_t rdba = adapter->rx_ring.dma; - uint32_t rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc); - uint32_t rctl; - uint32_t rxcsum; + uint32_t rdlen, rctl, rxcsum; + + if(adapter->rx_ps) { + rdlen = adapter->rx_ring.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.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 = E1000_READ_REG(&adapter->hw, RCTL); @@ -1189,13 +1360,27 @@ e1000_configure_rx(struct e1000_adapter *adapter) E1000_WRITE_REG(&adapter->hw, RDT, 0); /* Enable 82543 Receive Checksum Offload for TCP and UDP */ - if((adapter->hw.mac_type >= e1000_82543) && - (adapter->rx_csum == TRUE)) { + if(adapter->hw.mac_type >= e1000_82543) { rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM); - rxcsum |= E1000_RXCSUM_TUOFL; + if(adapter->rx_csum == TRUE) { + rxcsum |= E1000_RXCSUM_TUOFL; + + /* Enable 82573 IPv4 payload checksum for UDP fragments + * Must be used in conjunction with packet-split. */ + if((adapter->hw.mac_type > e1000_82547_rev_2) && + (adapter->rx_ps)) { + rxcsum |= E1000_RXCSUM_IPPCSE; + } + } else { + rxcsum &= ~E1000_RXCSUM_TUOFL; + /* don't need to clear IPPCSE as it defaults to 0 */ + } E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum); } + if (adapter->hw.mac_type == e1000_82573) + E1000_WRITE_REG(&adapter->hw, ERT, 0x0100); + /* Enable Receives */ E1000_WRITE_REG(&adapter->hw, RCTL, rctl); } @@ -1298,6 +1483,10 @@ 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); @@ -1314,16 +1503,19 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter) { struct e1000_desc_ring *rx_ring = &adapter->rx_ring; 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; + unsigned int i, j; /* Free all the Rx ring sk_buffs */ for(i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; if(buffer_info->skb) { - + ps_page = &rx_ring->ps_page[i]; + ps_page_dma = &rx_ring->ps_page_dma[i]; pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, @@ -1331,11 +1523,25 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter) dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; + + for(j = 0; j < PS_PAGE_BUFFERS; j++) { + if(!ps_page->ps_page[j]) break; + pci_unmap_single(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 */ @@ -1573,6 +1779,11 @@ e1000_watchdog_task(struct e1000_adapter *adapter) uint32_t link; e1000_check_for_link(&adapter->hw); + if (adapter->hw.mac_type == e1000_82573) { + e1000_enable_tx_pkt_filtering(&adapter->hw); + if(adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id) + e1000_update_mng_vlan(adapter); + } if((adapter->hw.media_type == e1000_media_type_internal_serdes) && !(E1000_READ_REG(&adapter->hw, TXCW) & E1000_TXCW_ANE)) @@ -1659,6 +1870,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) #define E1000_TX_FLAGS_CSUM 0x00000001 #define E1000_TX_FLAGS_VLAN 0x00000002 #define E1000_TX_FLAGS_TSO 0x00000004 +#define E1000_TX_FLAGS_IPV4 0x00000008 #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_SHIFT 16 @@ -1669,7 +1881,7 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb) struct e1000_context_desc *context_desc; unsigned int i; uint32_t cmd_length = 0; - uint16_t ipcse, tucse, mss; + uint16_t ipcse = 0, tucse, mss; uint8_t ipcss, ipcso, tucss, tucso, hdr_len; int err; @@ -1682,23 +1894,37 @@ e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb) hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); mss = skb_shinfo(skb)->tso_size; - skb->nh.iph->tot_len = 0; - skb->nh.iph->check = 0; - skb->h.th->check = ~csum_tcpudp_magic(skb->nh.iph->saddr, - skb->nh.iph->daddr, - 0, - IPPROTO_TCP, - 0); + if(skb->protocol == ntohs(ETH_P_IP)) { + skb->nh.iph->tot_len = 0; + skb->nh.iph->check = 0; + skb->h.th->check = + ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, + IPPROTO_TCP, + 0); + cmd_length = E1000_TXD_CMD_IP; + ipcse = skb->h.raw - skb->data - 1; +#ifdef NETIF_F_TSO_IPV6 + } else if(skb->protocol == ntohs(ETH_P_IPV6)) { + skb->nh.ipv6h->payload_len = 0; + skb->h.th->check = + ~csum_ipv6_magic(&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr, + 0, + IPPROTO_TCP, + 0); + ipcse = 0; +#endif + } ipcss = skb->nh.raw - skb->data; ipcso = (void *)&(skb->nh.iph->check) - (void *)skb->data; - ipcse = skb->h.raw - skb->data - 1; tucss = skb->h.raw - skb->data; tucso = (void *)&(skb->h.th->check) - (void *)skb->data; tucse = 0; cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE | - E1000_TXD_CMD_IP | E1000_TXD_CMD_TCP | - (skb->len - (hdr_len))); + E1000_TXD_CMD_TCP | (skb->len - (hdr_len))); i = adapter->tx_ring.next_to_use; context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i); @@ -1866,7 +2092,10 @@ e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags) if(likely(tx_flags & E1000_TX_FLAGS_TSO)) { txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D | E1000_TXD_CMD_TSE; - txd_upper |= (E1000_TXD_POPTS_IXSM | E1000_TXD_POPTS_TXSM) << 8; + txd_upper |= E1000_TXD_POPTS_TXSM << 8; + + if(likely(tx_flags & E1000_TX_FLAGS_IPV4)) + txd_upper |= E1000_TXD_POPTS_IXSM << 8; } if(likely(tx_flags & E1000_TX_FLAGS_CSUM)) { @@ -1941,6 +2170,53 @@ no_fifo_stall_required: return 0; } +#define MINIMUM_DHCP_PACKET_SIZE 282 +static inline int +e1000_transfer_dhcp_info(struct e1000_adapter *adapter, struct sk_buff *skb) +{ + struct e1000_hw *hw = &adapter->hw; + uint16_t length, offset; + if(vlan_tx_tag_present(skb)) { + if(!((vlan_tx_tag_get(skb) == adapter->hw.mng_cookie.vlan_id) && + ( adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) ) + return 0; + } + if(htons(ETH_P_IP) == skb->protocol) { + const struct iphdr *ip = skb->nh.iph; + if(IPPROTO_UDP == ip->protocol) { + struct udphdr *udp = (struct udphdr *)(skb->h.uh); + if(ntohs(udp->dest) == 67) { + offset = (uint8_t *)udp + 8 - skb->data; + length = skb->len - offset; + + return e1000_mng_write_dhcp_info(hw, + (uint8_t *)udp + 8, length); + } + } + } else if((skb->len > MINIMUM_DHCP_PACKET_SIZE) && (!skb->protocol)) { + struct ethhdr *eth = (struct ethhdr *) skb->data; + if((htons(ETH_P_IP) == eth->h_proto)) { + const struct iphdr *ip = + (struct iphdr *)((uint8_t *)skb->data+14); + if(IPPROTO_UDP == ip->protocol) { + struct udphdr *udp = + (struct udphdr *)((uint8_t *)ip + + (ip->ihl << 2)); + if(ntohs(udp->dest) == 67) { + offset = (uint8_t *)udp + 8 - skb->data; + length = skb->len - offset; + + return e1000_mng_write_dhcp_info(hw, + (uint8_t *)udp + 8, + length); + } + } + } + } + return 0; +} + #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) @@ -2008,6 +2284,9 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) local_irq_restore(flags); return NETDEV_TX_LOCKED; } + if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) ) + e1000_transfer_dhcp_info(adapter, skb); + /* need: count + 2 desc gap to keep tail from touching * head, otherwise try next time */ @@ -2044,6 +2323,12 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) else if(likely(e1000_tx_csum(adapter, skb))) tx_flags |= E1000_TX_FLAGS_CSUM; + /* Old method was to assume IPv4 packet by default if TSO was enabled. + * 82573 hardware supports TSO capabilities for IPv6 as well... + * no longer assume, we must. */ + if(likely(skb->protocol == ntohs(ETH_P_IP))) + tx_flags |= E1000_TX_FLAGS_IPV4; + e1000_tx_queue(adapter, e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss), tx_flags); @@ -2110,7 +2395,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) { struct e1000_adapter *adapter = netdev->priv; - int old_mtu = adapter->rx_buffer_len; int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || @@ -2119,29 +2403,45 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) return -EINVAL; } - if(max_frame <= MAXIMUM_ETHERNET_FRAME_SIZE) { - adapter->rx_buffer_len = E1000_RXBUFFER_2048; - - } else if(adapter->hw.mac_type < e1000_82543) { - DPRINTK(PROBE, ERR, "Jumbo Frames not supported on 82542\n"); +#define MAX_STD_JUMBO_FRAME_SIZE 9216 + /* might want this to be bigger enum check... */ + if (adapter->hw.mac_type == e1000_82573 && + max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { + DPRINTK(PROBE, ERR, "Jumbo Frames not supported " + "on 82573\n"); return -EINVAL; + } - } else if(max_frame <= E1000_RXBUFFER_4096) { - adapter->rx_buffer_len = E1000_RXBUFFER_4096; - - } else if(max_frame <= E1000_RXBUFFER_8192) { - adapter->rx_buffer_len = E1000_RXBUFFER_8192; - + if(adapter->hw.mac_type > e1000_82547_rev_2) { + adapter->rx_buffer_len = max_frame; + E1000_ROUNDUP(adapter->rx_buffer_len, 1024); } else { - adapter->rx_buffer_len = E1000_RXBUFFER_16384; + if(unlikely((adapter->hw.mac_type < e1000_82543) && + (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { + DPRINTK(PROBE, ERR, "Jumbo Frames not supported " + "on 82542\n"); + return -EINVAL; + + } else { + if(max_frame <= E1000_RXBUFFER_2048) { + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + } else if(max_frame <= E1000_RXBUFFER_4096) { + adapter->rx_buffer_len = E1000_RXBUFFER_4096; + } else if(max_frame <= E1000_RXBUFFER_8192) { + adapter->rx_buffer_len = E1000_RXBUFFER_8192; + } else if(max_frame <= E1000_RXBUFFER_16384) { + adapter->rx_buffer_len = E1000_RXBUFFER_16384; + } + } } - if(old_mtu != adapter->rx_buffer_len && netif_running(netdev)) { + netdev->mtu = new_mtu; + + if(netif_running(netdev)) { e1000_down(adapter); e1000_up(adapter); } - netdev->mtu = new_mtu; adapter->hw.max_frame_size = max_frame; return 0; @@ -2232,6 +2532,17 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->stats.tsctc += E1000_READ_REG(hw, TSCTC); adapter->stats.tsctfc += E1000_READ_REG(hw, TSCTFC); } + if(hw->mac_type > e1000_82547_rev_2) { + adapter->stats.iac += E1000_READ_REG(hw, IAC); + adapter->stats.icrxoc += E1000_READ_REG(hw, ICRXOC); + adapter->stats.icrxptc += E1000_READ_REG(hw, ICRXPTC); + adapter->stats.icrxatc += E1000_READ_REG(hw, ICRXATC); + adapter->stats.ictxptc += E1000_READ_REG(hw, ICTXPTC); + adapter->stats.ictxatc += E1000_READ_REG(hw, ICTXATC); + adapter->stats.ictxqec += E1000_READ_REG(hw, ICTXQEC); + adapter->stats.ictxqmtc += E1000_READ_REG(hw, ICTXQMTC); + adapter->stats.icrxdmtc += E1000_READ_REG(hw, ICRXDMTC); + } /* Fill out the OS statistics structure */ @@ -2337,7 +2648,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) } for(i = 0; i < E1000_MAX_INTR; i++) - if(unlikely(!e1000_clean_rx_irq(adapter) & + if(unlikely(!adapter->clean_rx(adapter) & !e1000_clean_tx_irq(adapter))) break; @@ -2363,7 +2674,7 @@ e1000_clean(struct net_device *netdev, int *budget) int work_done = 0; tx_cleaned = e1000_clean_tx_irq(adapter); - e1000_clean_rx_irq(adapter, &work_done, work_to_do); + adapter->clean_rx(adapter, &work_done, work_to_do); *budget -= work_done; netdev->quota -= work_done; @@ -2501,41 +2812,57 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) /** * e1000_rx_checksum - Receive Checksum Offload for 82543 - * @adapter: board private structure - * @rx_desc: receive descriptor - * @sk_buff: socket buffer with received data + * @adapter: board private structure + * @status_err: receive descriptor status and error fields + * @csum: receive descriptor csum field + * @sk_buff: socket buffer with received data **/ static inline void e1000_rx_checksum(struct e1000_adapter *adapter, - struct e1000_rx_desc *rx_desc, - struct sk_buff *skb) + uint32_t status_err, uint32_t csum, + struct sk_buff *skb) { + uint16_t status = (uint16_t)status_err; + uint8_t errors = (uint8_t)(status_err >> 24); + skb->ip_summed = CHECKSUM_NONE; + /* 82543 or newer only */ - if(unlikely((adapter->hw.mac_type < e1000_82543) || + if(unlikely(adapter->hw.mac_type < e1000_82543)) return; /* Ignore Checksum bit is set */ - (rx_desc->status & E1000_RXD_STAT_IXSM) || - /* TCP Checksum has not been calculated */ - (!(rx_desc->status & E1000_RXD_STAT_TCPCS)))) { - skb->ip_summed = CHECKSUM_NONE; - return; - } - - /* At this point we know the hardware did the TCP checksum */ - /* now look at the TCP checksum error bit */ - if(rx_desc->errors & E1000_RXD_ERR_TCPE) { + if(unlikely(status & E1000_RXD_STAT_IXSM)) return; + /* TCP/UDP checksum error bit is set */ + if(unlikely(errors & E1000_RXD_ERR_TCPE)) { /* let the stack verify checksum errors */ - skb->ip_summed = CHECKSUM_NONE; adapter->hw_csum_err++; + return; + } + /* TCP/UDP Checksum has not been calculated */ + if(adapter->hw.mac_type <= e1000_82547_rev_2) { + if(!(status & E1000_RXD_STAT_TCPCS)) + return; } else { + if(!(status & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))) + return; + } + /* It must be a TCP or UDP packet with a valid checksum */ + if (likely(status & E1000_RXD_STAT_TCPCS)) { /* TCP checksum is good */ skb->ip_summed = CHECKSUM_UNNECESSARY; - adapter->hw_csum_good++; + } else if (adapter->hw.mac_type > e1000_82547_rev_2) { + /* IP fragment with UDP payload */ + /* Hardware complements the payload checksum, so we undo it + * and then put the value in host order for further stack use. + */ + csum = ntohl(csum ^ 0xFFFF); + skb->csum = csum; + skb->ip_summed = CHECKSUM_HW; } + adapter->hw_csum_good++; } /** - * e1000_clean_rx_irq - Send received data up the network stack + * e1000_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure **/ @@ -2608,15 +2935,17 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter) skb_put(skb, length - ETHERNET_FCS_SIZE); /* Receive Checksum Offload */ - e1000_rx_checksum(adapter, rx_desc, skb); - + e1000_rx_checksum(adapter, + (uint32_t)(rx_desc->status) | + ((uint32_t)(rx_desc->errors) << 24), + rx_desc->csum, skb); skb->protocol = eth_type_trans(skb, netdev); #ifdef CONFIG_E1000_NAPI if(unlikely(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP))) { vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(rx_desc->special) & - E1000_RXD_SPC_VLAN_MASK); + le16_to_cpu(rx_desc->special) & + E1000_RXD_SPC_VLAN_MASK); } else { netif_receive_skb(skb); } @@ -2639,16 +2968,142 @@ next_desc: rx_desc = E1000_RX_DESC(*rx_ring, i); } - rx_ring->next_to_clean = i; + adapter->alloc_rx_buf(adapter); + + return cleaned; +} + +/** + * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split + * @adapter: board private structure + **/ + +static boolean_t +#ifdef CONFIG_E1000_NAPI +e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done, + int work_to_do) +#else +e1000_clean_rx_irq_ps(struct e1000_adapter *adapter) +#endif +{ + struct e1000_desc_ring *rx_ring = &adapter->rx_ring; + union e1000_rx_desc_packet_split *rx_desc; + struct net_device *netdev = adapter->netdev; + struct pci_dev *pdev = adapter->pdev; + 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; + uint32_t length, staterr; + boolean_t cleaned = FALSE; + + i = rx_ring->next_to_clean; + rx_desc = E1000_RX_DESC_PS(*rx_ring, i); + staterr = rx_desc->wb.middle.status_error; + + while(staterr & E1000_RXD_STAT_DD) { + buffer_info = &rx_ring->buffer_info[i]; + ps_page = &rx_ring->ps_page[i]; + ps_page_dma = &rx_ring->ps_page_dma[i]; +#ifdef CONFIG_E1000_NAPI + if(unlikely(*work_done >= work_to_do)) + break; + (*work_done)++; +#endif + cleaned = TRUE; + pci_unmap_single(pdev, buffer_info->dma, + buffer_info->length, + PCI_DMA_FROMDEVICE); + + skb = buffer_info->skb; + + 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; + } - e1000_alloc_rx_buffers(adapter); + 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); + + for(j = 0; j < PS_PAGE_BUFFERS; j++) { + if(!(length = le16_to_cpu(rx_desc->wb.upper.length[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; + skb_shinfo(skb)->frags[j].page = + ps_page->ps_page[j]; + ps_page->ps_page[j] = NULL; + skb_shinfo(skb)->frags[j].page_offset = 0; + skb_shinfo(skb)->frags[j].size = length; + skb_shinfo(skb)->nr_frags++; + skb->len += length; + skb->data_len += length; + } + + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + skb->protocol = eth_type_trans(skb, netdev); + +#ifdef HAVE_RX_ZERO_COPY + if(likely(rx_desc->wb.upper.header_status & + E1000_RXDPS_HDRSTAT_HDRSP)) + skb_shinfo(skb)->zero_copy = TRUE; +#endif +#ifdef CONFIG_E1000_NAPI + if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { + vlan_hwaccel_receive_skb(skb, adapter->vlgrp, + le16_to_cpu(rx_desc->wb.middle.vlan & + E1000_RXD_SPC_VLAN_MASK)); + } else { + netif_receive_skb(skb); + } +#else /* CONFIG_E1000_NAPI */ + if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { + vlan_hwaccel_rx(skb, adapter->vlgrp, + le16_to_cpu(rx_desc->wb.middle.vlan & + E1000_RXD_SPC_VLAN_MASK)); + } else { + netif_rx(skb); + } +#endif /* CONFIG_E1000_NAPI */ + netdev->last_rx = jiffies; + +next_desc: + rx_desc->wb.middle.status_error &= ~0xFF; + buffer_info->skb = NULL; + if(unlikely(++i == rx_ring->count)) i = 0; + + rx_desc = E1000_RX_DESC_PS(*rx_ring, i); + staterr = rx_desc->wb.middle.status_error; + } + rx_ring->next_to_clean = i; + adapter->alloc_rx_buf(adapter); return cleaned; } /** - * e1000_alloc_rx_buffers - Replace used receive buffers + * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended * @adapter: address of board private structure **/ @@ -2752,6 +3207,95 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter) rx_ring->next_to_use = i; } +/** + * 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_desc_ring *rx_ring = &adapter->rx_ring; + 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(!buffer_info->skb) { + rx_desc = E1000_RX_DESC_PS(*rx_ring, i); + + for(j = 0; j < PS_PAGE_BUFFERS; j++) { + if(unlikely(!ps_page->ps_page[j])) { + ps_page->ps_page[j] = + alloc_page(GFP_ATOMIC); + if(unlikely(!ps_page->ps_page[j])) + 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]); + } + + skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN); + + if(unlikely(!skb)) + 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); + + skb->dev = netdev; + + 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 & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) { + /* 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. + */ + E1000_WRITE_REG(&adapter->hw, RDT, i<<1); + } + + 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: + rx_ring->next_to_use = i; +} + /** * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers. * @adapter: @@ -2986,6 +3530,7 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) rctl |= E1000_RCTL_VFE; rctl &= ~E1000_RCTL_CFIEN; E1000_WRITE_REG(&adapter->hw, RCTL, rctl); + e1000_update_mng_vlan(adapter); } else { /* disable VLAN tag insert/strip */ ctrl = E1000_READ_REG(&adapter->hw, CTRL); @@ -2996,6 +3541,10 @@ e1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl &= ~E1000_RCTL_VFE; E1000_WRITE_REG(&adapter->hw, RCTL, rctl); + if(adapter->mng_vlan_id != (uint16_t)E1000_MNG_VLAN_NONE) { + e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); + adapter->mng_vlan_id = E1000_MNG_VLAN_NONE; + } } e1000_irq_enable(adapter); @@ -3006,7 +3555,10 @@ e1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) { struct e1000_adapter *adapter = netdev->priv; uint32_t vfta, index; - + if((adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && + (vid == adapter->mng_vlan_id)) + return; /* add VID to filter table */ index = (vid >> 5) & 0x7F; vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); @@ -3027,6 +3579,10 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) e1000_irq_enable(adapter); + if((adapter->hw.mng_cookie.status & + E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && + (vid == adapter->mng_vlan_id)) + return; /* remove VID from filter table */ index = (vid >> 5) & 0x7F; vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); @@ -3102,7 +3658,7 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - uint32_t ctrl, ctrl_ext, rctl, manc, status; + uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm; uint32_t wufc = adapter->wol; netif_device_detach(netdev); @@ -3144,6 +3700,9 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext); } + /* Allow time for pending master requests to run */ + e1000_disable_pciex_master(&adapter->hw); + E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUFC, wufc); pci_enable_wake(pdev, 3, 1); @@ -3168,6 +3727,16 @@ e1000_suspend(struct pci_dev *pdev, uint32_t state) } } + switch(adapter->hw.mac_type) { + case e1000_82573: + swsm = E1000_READ_REG(&adapter->hw, SWSM); + E1000_WRITE_REG(&adapter->hw, SWSM, + swsm & ~E1000_SWSM_DRV_LOAD); + break; + default: + break; + } + pci_disable_device(pdev); state = (state > 0) ? 3 : 0; @@ -3182,7 +3751,7 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev->priv; - uint32_t manc, ret; + uint32_t manc, ret, swsm; pci_set_power_state(pdev, 0); pci_restore_state(pdev); @@ -3207,10 +3776,19 @@ e1000_resume(struct pci_dev *pdev) E1000_WRITE_REG(&adapter->hw, MANC, manc); } + switch(adapter->hw.mac_type) { + case e1000_82573: + swsm = E1000_READ_REG(&adapter->hw, SWSM); + E1000_WRITE_REG(&adapter->hw, SWSM, + swsm | E1000_SWSM_DRV_LOAD); + break; + default: + break; + } + return 0; } #endif - #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index 2efa3b1b64dc..b1915e8eb564 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -101,6 +101,29 @@ typedef enum { (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ ((offset) << 2))) +#define E1000_READ_REG_ARRAY_DWORD E1000_READ_REG_ARRAY +#define E1000_WRITE_REG_ARRAY_DWORD E1000_WRITE_REG_ARRAY + +#define E1000_WRITE_REG_ARRAY_WORD(a, reg, offset, value) ( \ + writew((value), ((a)->hw_addr + \ + (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ + ((offset) << 1)))) + +#define E1000_READ_REG_ARRAY_WORD(a, reg, offset) ( \ + readw((a)->hw_addr + \ + (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ + ((offset) << 1))) + +#define E1000_WRITE_REG_ARRAY_BYTE(a, reg, offset, value) ( \ + writeb((value), ((a)->hw_addr + \ + (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ + (offset)))) + +#define E1000_READ_REG_ARRAY_BYTE(a, reg, offset) ( \ + readb((a)->hw_addr + \ + (((a)->mac_type >= e1000_82543) ? E1000_##reg : E1000_82542_##reg) + \ + (offset))) + #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS) #endif /* _E1000_OSDEP_H_ */ -- cgit v1.2.2 From 0e6ef3e02b6f07e37ba1c1abc059f8bee4e0847f Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:44:14 -0700 Subject: [PATCH] e1000:Fix Packet Buffer Allocation logic for 82547_rev_2 Fix Packet Buffer Allocation logic for 82547_rev_2 controller Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 5e6e1f7fd777..13bde9090537 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -417,6 +417,7 @@ e1000_reset(struct e1000_adapter *adapter) switch (adapter->hw.mac_type) { case e1000_82547: + case e1000_82547_rev_2: pba = E1000_PBA_30K; break; case e1000_82573: -- cgit v1.2.2 From 1125ecbc0a89db07bb4eb1ba892a23367c3bdeb5 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:44:25 -0700 Subject: [PATCH] e1000:Adjust flow control watermarks for Jumbo Frames Adjust flow control watermarks for Jumbo Frames Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_main.c net-drivers-2.6/drivers/net/e1000.new/e1000_main.c --- drivers/net/e1000/e1000_main.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 13bde9090537..24d96c02b509 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -409,7 +409,10 @@ e1000_down(struct e1000_adapter *adapter) void e1000_reset(struct e1000_adapter *adapter) { + struct net_device *netdev = adapter->netdev; uint32_t pba, manc; + uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; + uint16_t fc_low_water_mark = E1000_FC_LOW_DIFF; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. @@ -428,6 +431,16 @@ e1000_reset(struct e1000_adapter *adapter) break; } + if((adapter->hw.mac_type != e1000_82573) && + (adapter->rx_buffer_len > E1000_RXBUFFER_8192)) { + pba -= 8; /* allocate more FIFO for Tx */ + /* send an XOFF when there is enough space in the + * Rx FIFO to hold one extra full size Rx packet + */ + fc_high_water_mark = netdev->mtu + ENET_HEADER_SIZE + + ETHERNET_FCS_SIZE + 1; + fc_low_water_mark = fc_high_water_mark + 8; + } if(adapter->hw.mac_type == e1000_82547) { @@ -442,9 +455,9 @@ e1000_reset(struct e1000_adapter *adapter) /* flow control settings */ adapter->hw.fc_high_water = (pba << E1000_PBA_BYTES_SHIFT) - - E1000_FC_HIGH_DIFF; + fc_high_water_mark; adapter->hw.fc_low_water = (pba << E1000_PBA_BYTES_SHIFT) - - E1000_FC_LOW_DIFF; + fc_low_water_mark; adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; adapter->hw.fc_send_xon = 1; adapter->hw.fc = adapter->hw.original_fc; -- cgit v1.2.2 From 2648345fcbadfae8e7113112ff9402e465a184dc Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:44:46 -0700 Subject: [PATCH] e1000:Driver version,white space,comments,device id Driver version, white space, comments, device id & other Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/e1000/e1000_ethtool.c net-drivers-2.6/drivers/net/e1000.new/e1000_ethtool.c --- drivers/net/e1000/e1000.h | 8 +- drivers/net/e1000/e1000_ethtool.c | 24 +++-- drivers/net/e1000/e1000_hw.c | 3 +- drivers/net/e1000/e1000_hw.h | 2 +- drivers/net/e1000/e1000_main.c | 199 +++++++++++++++++--------------------- drivers/net/e1000/e1000_osdep.h | 2 +- drivers/net/e1000/e1000_param.c | 3 +- 7 files changed, 106 insertions(+), 135 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 19858c267532..af1e82c5b808 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -139,9 +139,9 @@ struct e1000_adapter; /* How many Rx Buffers do we bundle into one write to the hardware ? */ #define E1000_RX_BUFFER_WRITE 16 /* Must be power of 2 */ -#define AUTO_ALL_MODES 0 -#define E1000_EEPROM_82544_APM 0x0004 -#define E1000_EEPROM_APME 0x0400 +#define AUTO_ALL_MODES 0 +#define E1000_EEPROM_82544_APM 0x0400 +#define E1000_EEPROM_APME 0x0400 #ifndef E1000_MASTER_SLAVE /* Switch to override PHY master/slave setting */ diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index fae585453463..237247f74df4 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -69,6 +69,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, { "rx_fifo_errors", E1000_STAT(net_stats.rx_fifo_errors) }, + { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, @@ -593,7 +594,7 @@ e1000_set_ringparam(struct net_device *netdev, tx_old = adapter->tx_ring; rx_old = adapter->rx_ring; - if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + if((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; if(netif_running(adapter->netdev)) @@ -784,8 +785,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) /* Hook up test interrupt handler just for this test */ if(!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { shared_int = FALSE; - } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, - netdev->name, netdev)){ + } else if(request_irq(irq, &e1000_test_intr, SA_SHIRQ, + netdev->name, netdev)){ *data = 1; return -1; } @@ -842,10 +843,8 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) * test failed. */ adapter->test_icr = 0; - E1000_WRITE_REG(&adapter->hw, IMC, - (~mask & 0x00007FFF)); - E1000_WRITE_REG(&adapter->hw, ICS, - (~mask & 0x00007FFF)); + E1000_WRITE_REG(&adapter->hw, IMC, ~mask & 0x00007FFF); + E1000_WRITE_REG(&adapter->hw, ICS, ~mask & 0x00007FFF); msec_delay(10); if(adapter->test_icr) { @@ -1010,7 +1009,7 @@ e1000_setup_desc_rings(struct e1000_adapter *adapter) struct e1000_rx_desc *rx_desc = E1000_RX_DESC(*rxdr, i); struct sk_buff *skb; - if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, + if(!(skb = alloc_skb(E1000_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL))) { ret_val = 6; goto err_nomem; @@ -1387,13 +1386,12 @@ static int e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) { *data = 0; - if (adapter->hw.media_type == e1000_media_type_internal_serdes) { int i = 0; adapter->hw.serdes_link_down = TRUE; - /* on some blade server designs link establishment */ - /* could take as long as 2-3 minutes. */ + /* On some blade server designs, link establishment + * could take as long as 2-3 minutes */ do { e1000_check_for_link(&adapter->hw); if (adapter->hw.serdes_link_down == FALSE) @@ -1401,7 +1399,7 @@ e1000_link_test(struct e1000_adapter *adapter, uint64_t *data) msec_delay(20); } while (i++ < 3750); - *data = 1; + *data = 1; } else { e1000_check_for_link(&adapter->hw); if(adapter->hw.autoneg) /* if auto_neg is set wait for it */ diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index b7a7ceb67f47..723589b28be5 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -144,7 +144,6 @@ e1000_phy_init_script(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_init_script"); - if(hw->phy_init_script) { msec_delay(20); diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index 1573f608fb68..a0263ee96c6b 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 24d96c02b509..325495b8b60c 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -29,33 +29,9 @@ #include "e1000.h" /* Change Log - * 5.3.12 6/7/04 - * - kcompat NETIF_MSG for older kernels (2.4.9) - * - if_mii support and associated kcompat for older kernels - * - More errlogging support from Jon Mason - * - Fix TSO issues on PPC64 machines -- Jon Mason - * - * 5.7.1 12/16/04 - * - Resurrect 82547EI/GI related fix in e1000_intr to avoid deadlocks. This - * fix was removed as it caused system instability. The suspected cause of - * this is the called to e1000_irq_disable in e1000_intr. Inlined the - * required piece of e1000_irq_disable into e1000_intr - Anton Blanchard - * 5.7.0 12/10/04 - * - include fix to the condition that determines when to quit NAPI - Robert Olsson - * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down - * 5.6.5 11/01/04 - * - Enabling NETIF_F_SG without checksum offload is illegal - - John Mason - * 5.6.3 10/26/04 - * - Remove redundant initialization - Jamal Hadi - * - Reset buffer_info->dma in tx resource cleanup logic - * 5.6.2 10/12/04 - * - Avoid filling tx_ring completely - shemminger@osdl.org - * - Replace schedule_timeout() with msleep()/msleep_interruptible() - - * nacc@us.ibm.com - * - Sparse cleanup - shemminger@osdl.org - * - Fix tx resource cleanup logic - * - LLTX support - ak@suse.de and hadi@cyberus.ca + * 6.0.44+ 2/15/05 + * o applied Anton's patch to resolve tx hang in hardware + * o Applied Andrew Mortons patch - e1000 stops working after resume */ char e1000_driver_name[] = "e1000"; @@ -65,7 +41,7 @@ char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "5.7.6-k2"DRIVERNAPI +#define DRV_VERSION "6.0.54-k2"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; char e1000_copyright[] = "Copyright (c) 1999-2004 Intel Corporation."; @@ -96,6 +72,7 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x1017), INTEL_E1000_ETHERNET_DEVICE(0x1018), INTEL_E1000_ETHERNET_DEVICE(0x1019), + INTEL_E1000_ETHERNET_DEVICE(0x101A), INTEL_E1000_ETHERNET_DEVICE(0x101D), INTEL_E1000_ETHERNET_DEVICE(0x101E), INTEL_E1000_ETHERNET_DEVICE(0x1026), @@ -110,6 +87,9 @@ static struct pci_device_id e1000_pci_tbl[] = { INTEL_E1000_ETHERNET_DEVICE(0x107B), INTEL_E1000_ETHERNET_DEVICE(0x107C), INTEL_E1000_ETHERNET_DEVICE(0x108A), + INTEL_E1000_ETHERNET_DEVICE(0x108B), + INTEL_E1000_ETHERNET_DEVICE(0x108C), + INTEL_E1000_ETHERNET_DEVICE(0x1099), /* required last entry */ {0,} }; @@ -350,8 +330,11 @@ e1000_up(struct e1000_adapter *adapter) #endif if((err = request_irq(adapter->pdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, - netdev->name, netdev))) + netdev->name, netdev))) { + DPRINTK(PROBE, ERR, + "Unable to allocate interrupt Error: %d\n", err); return err; + } mod_timer(&adapter->watchdog_timer, jiffies); @@ -636,7 +619,7 @@ e1000_probe(struct pci_dev *pdev, /* copy the MAC address out of the EEPROM */ - if (e1000_read_mac_addr(&adapter->hw)) + if(e1000_read_mac_addr(&adapter->hw)) DPRINTK(PROBE, ERR, "EEPROM Read Error\n"); memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); @@ -963,12 +946,10 @@ e1000_check_64k_bound(struct e1000_adapter *adapter, unsigned long begin = (unsigned long) start; unsigned long end = begin + len; - /* first rev 82545 and 82546 need to not allow any memory - * write location to cross a 64k boundary due to errata 23 */ + /* First rev 82545 and 82546 need to not allow any memory + * write location to cross 64k boundary due to errata 23 */ if (adapter->hw.mac_type == e1000_82545 || - adapter->hw.mac_type == e1000_82546 ) { - - /* check buffer doesn't cross 64kB */ + adapter->hw.mac_type == e1000_82546) { return ((begin ^ (end - 1)) >> 16) != 0 ? FALSE : TRUE; } @@ -992,8 +973,8 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter) size = sizeof(struct e1000_buffer) * txdr->count; txdr->buffer_info = vmalloc(size); if(!txdr->buffer_info) { - DPRINTK(PROBE, ERR, - "Unable to Allocate Memory for the Transmit descriptor ring\n"); + DPRINTK(PROBE, ERR, + "Unable to allocate memory for the transmit descriptor ring\n"); return -ENOMEM; } memset(txdr->buffer_info, 0, size); @@ -1006,38 +987,38 @@ e1000_setup_tx_resources(struct e1000_adapter *adapter) txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); if(!txdr->desc) { setup_tx_desc_die: - DPRINTK(PROBE, ERR, - "Unable to Allocate Memory for the Transmit descriptor ring\n"); vfree(txdr->buffer_info); + DPRINTK(PROBE, ERR, + "Unable to allocate memory for the transmit descriptor ring\n"); return -ENOMEM; } - /* fix for errata 23, cant cross 64kB boundary */ + /* Fix for errata 23, can't cross 64kB boundary */ if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) { void *olddesc = txdr->desc; dma_addr_t olddma = txdr->dma; - DPRINTK(TX_ERR,ERR,"txdr align check failed: %u bytes at %p\n", - txdr->size, txdr->desc); - /* try again, without freeing the previous */ + DPRINTK(TX_ERR, ERR, "txdr align check failed: %u bytes " + "at %p\n", txdr->size, txdr->desc); + /* Try again, without freeing the previous */ txdr->desc = pci_alloc_consistent(pdev, txdr->size, &txdr->dma); - /* failed allocation, critial failure */ if(!txdr->desc) { + /* Failed allocation, critical failure */ pci_free_consistent(pdev, txdr->size, olddesc, olddma); goto setup_tx_desc_die; } if (!e1000_check_64k_bound(adapter, txdr->desc, txdr->size)) { /* give up */ - pci_free_consistent(pdev, txdr->size, - txdr->desc, txdr->dma); + pci_free_consistent(pdev, txdr->size, txdr->desc, + txdr->dma); pci_free_consistent(pdev, txdr->size, olddesc, olddma); DPRINTK(PROBE, ERR, - "Unable to Allocate aligned Memory for the Transmit" - " descriptor ring\n"); + "Unable to allocate aligned memory " + "for the transmit descriptor ring\n"); vfree(txdr->buffer_info); return -ENOMEM; } else { - /* free old, move on with the new one since its okay */ + /* Free old allocation, new allocation was successful */ pci_free_consistent(pdev, txdr->size, olddesc, olddma); } } @@ -1144,8 +1125,8 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter) size = sizeof(struct e1000_buffer) * rxdr->count; rxdr->buffer_info = vmalloc(size); if(!rxdr->buffer_info) { - DPRINTK(PROBE, ERR, - "Unable to Allocate Memory for the Recieve descriptor ring\n"); + DPRINTK(PROBE, ERR, + "Unable to allocate memory for the receive descriptor ring\n"); return -ENOMEM; } memset(rxdr->buffer_info, 0, size); @@ -1185,43 +1166,42 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter) if(!rxdr->desc) { setup_rx_desc_die: - DPRINTK(PROBE, ERR, - "Unble to Allocate Memory for the Recieve descriptor ring\n"); vfree(rxdr->buffer_info); kfree(rxdr->ps_page); kfree(rxdr->ps_page_dma); + DPRINTK(PROBE, ERR, + "Unable to allocate memory for the receive descriptor ring\n"); return -ENOMEM; } - /* fix for errata 23, cant cross 64kB boundary */ + /* Fix for errata 23, can't cross 64kB boundary */ if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) { void *olddesc = rxdr->desc; dma_addr_t olddma = rxdr->dma; - DPRINTK(RX_ERR,ERR, - "rxdr align check failed: %u bytes at %p\n", - rxdr->size, rxdr->desc); - /* try again, without freeing the previous */ + DPRINTK(RX_ERR, ERR, "rxdr align check failed: %u bytes " + "at %p\n", rxdr->size, rxdr->desc); + /* Try again, without freeing the previous */ rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma); - /* failed allocation, critial failure */ if(!rxdr->desc) { + /* Failed allocation, critical failure */ pci_free_consistent(pdev, rxdr->size, olddesc, olddma); goto setup_rx_desc_die; } if (!e1000_check_64k_bound(adapter, rxdr->desc, rxdr->size)) { /* give up */ - pci_free_consistent(pdev, rxdr->size, - rxdr->desc, rxdr->dma); + pci_free_consistent(pdev, rxdr->size, rxdr->desc, + rxdr->dma); pci_free_consistent(pdev, rxdr->size, olddesc, olddma); - DPRINTK(PROBE, ERR, - "Unable to Allocate aligned Memory for the" - " Receive descriptor ring\n"); + DPRINTK(PROBE, ERR, + "Unable to allocate aligned memory " + "for the receive descriptor ring\n"); vfree(rxdr->buffer_info); kfree(rxdr->ps_page); kfree(rxdr->ps_page_dma); return -ENOMEM; } else { - /* free old, move on with the new one since its okay */ + /* Free old allocation, new allocation was successful */ pci_free_consistent(pdev, rxdr->size, olddesc, olddma); } } @@ -1234,7 +1214,7 @@ setup_rx_desc_die: } /** - * e1000_setup_rctl - configure the receive control register + * e1000_setup_rctl - configure the receive control registers * @adapter: Board private structure **/ @@ -1426,13 +1406,11 @@ static inline void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info) { - struct pci_dev *pdev = adapter->pdev; - if(buffer_info->dma) { - pci_unmap_page(pdev, - buffer_info->dma, - buffer_info->length, - PCI_DMA_TODEVICE); + pci_unmap_page(adapter->pdev, + buffer_info->dma, + buffer_info->length, + PCI_DMA_TODEVICE); buffer_info->dma = 0; } if(buffer_info->skb) { @@ -1457,7 +1435,7 @@ e1000_clean_tx_ring(struct e1000_adapter *adapter) /* Free all the Tx ring sk_buffs */ if (likely(adapter->previous_buffer_info.skb != NULL)) { - e1000_unmap_and_free_tx_resource(adapter, + e1000_unmap_and_free_tx_resource(adapter, &adapter->previous_buffer_info); } @@ -1659,15 +1637,15 @@ e1000_set_multi(struct net_device *netdev) struct e1000_adapter *adapter = netdev->priv; struct e1000_hw *hw = &adapter->hw; struct dev_mc_list *mc_ptr; + unsigned long flags; uint32_t rctl; uint32_t hash_value; int i; - unsigned long flags; - - /* Check for Promiscuous and All Multicast modes */ spin_lock_irqsave(&adapter->tx_lock, flags); + /* Check for Promiscuous and All Multicast modes */ + rctl = E1000_READ_REG(hw, RCTL); if(netdev->flags & IFF_PROMISC) { @@ -1874,7 +1852,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) /* Cause software interrupt to ensure rx ring is cleaned */ E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0); - /* Force detection of hung controller every watchdog period*/ + /* Force detection of hung controller every watchdog period */ adapter->detect_tx_hung = TRUE; /* Reset the timer */ @@ -2255,7 +2233,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) #ifdef NETIF_F_TSO mss = skb_shinfo(skb)->tso_size; - /* The controller does a simple calculation to + /* The controller does a simple calculation to * make sure there is enough room in the FIFO before * initiating the DMA for each buffer. The calc is: * 4 = ceil(buffer len/mss). To make sure we don't @@ -2268,7 +2246,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if((mss) || (skb->ip_summed == CHECKSUM_HW)) count++; - count++; /* for sentinel desc */ + count++; #else if(skb->ip_summed == CHECKSUM_HW) count++; @@ -2658,7 +2636,7 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) */ if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2){ atomic_inc(&adapter->irq_sem); - E1000_WRITE_REG(&adapter->hw, IMC, ~0); + E1000_WRITE_REG(hw, IMC, ~0); } for(i = 0; i < E1000_MAX_INTR; i++) @@ -2686,7 +2664,7 @@ e1000_clean(struct net_device *netdev, int *budget) int work_to_do = min(*budget, netdev->quota); int tx_cleaned; int work_done = 0; - + tx_cleaned = e1000_clean_tx_irq(adapter); adapter->clean_rx(adapter, &work_done, work_to_do); @@ -2776,9 +2754,9 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) netif_wake_queue(netdev); spin_unlock(&adapter->tx_lock); - if(adapter->detect_tx_hung) { - /* detect a transmit hang in hardware, this serializes the + + /* Detect a transmit hang in hardware, this serializes the * check with the clearing of time_stamp and movement of i */ adapter->detect_tx_hung = FALSE; if (tx_ring->buffer_info[i].dma && @@ -2923,7 +2901,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter) if(unlikely(!(rx_desc->status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" - " buffers\n", netdev->name); + " buffers\n", netdev->name); dev_kfree_skb_irq(skb); goto next_desc; } @@ -3130,43 +3108,43 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter) struct e1000_rx_desc *rx_desc; struct e1000_buffer *buffer_info; struct sk_buff *skb; - unsigned int i, bufsz; + unsigned int i; + unsigned int bufsz = adapter->rx_buffer_len + NET_IP_ALIGN; i = rx_ring->next_to_use; buffer_info = &rx_ring->buffer_info[i]; while(!buffer_info->skb) { - bufsz = adapter->rx_buffer_len + NET_IP_ALIGN; - skb = dev_alloc_skb(bufsz); + if(unlikely(!skb)) { /* Better luck next round */ break; } - /* fix for errata 23, cant cross 64kB boundary */ + /* Fix for errata 23, can't cross 64kB boundary */ if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { struct sk_buff *oldskb = skb; - DPRINTK(RX_ERR,ERR, - "skb align check failed: %u bytes at %p\n", - bufsz, skb->data); - /* try again, without freeing the previous */ + DPRINTK(RX_ERR, ERR, "skb align check failed: %u bytes " + "at %p\n", bufsz, skb->data); + /* Try again, without freeing the previous */ skb = dev_alloc_skb(bufsz); + /* Failed allocation, critical failure */ if (!skb) { dev_kfree_skb(oldskb); break; } + if (!e1000_check_64k_bound(adapter, skb->data, bufsz)) { /* give up */ dev_kfree_skb(skb); dev_kfree_skb(oldskb); break; /* while !buffer_info->skb */ } else { - /* move on with the new one */ + /* Use new allocation */ dev_kfree_skb(oldskb); } } - /* 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 @@ -3182,25 +3160,23 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter) adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - /* fix for errata 23, cant cross 64kB boundary */ - if(!e1000_check_64k_bound(adapter, - (void *)(unsigned long)buffer_info->dma, - adapter->rx_buffer_len)) { - DPRINTK(RX_ERR,ERR, - "dma align check failed: %u bytes at %ld\n", - adapter->rx_buffer_len, (unsigned long)buffer_info->dma); - + /* Fix for errata 23, can't cross 64kB boundary */ + if (!e1000_check_64k_bound(adapter, + (void *)(unsigned long)buffer_info->dma, + adapter->rx_buffer_len)) { + DPRINTK(RX_ERR, ERR, + "dma align check failed: %u bytes at %p\n", + adapter->rx_buffer_len, + (void *)(unsigned long)buffer_info->dma); dev_kfree_skb(skb); buffer_info->skb = NULL; - pci_unmap_single(pdev, - buffer_info->dma, + pci_unmap_single(pdev, buffer_info->dma, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); break; /* while !buffer_info->skb */ } - rx_desc = E1000_RX_DESC(*rx_ring, i); rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); @@ -3210,7 +3186,6 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter) * applicable for weak-ordered memory model archs, * such as IA-64). */ wmb(); - E1000_WRITE_REG(&adapter->hw, RDT, i); } @@ -3483,9 +3458,10 @@ void e1000_pci_set_mwi(struct e1000_hw *hw) { struct e1000_adapter *adapter = hw->back; + int ret_val = pci_set_mwi(adapter->pdev); - int ret; - ret = pci_set_mwi(adapter->pdev); + if(ret_val) + DPRINTK(PROBE, ERR, "Error in setting MWI\n"); } void @@ -3643,8 +3619,7 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx) break; case SPEED_1000 + DUPLEX_HALF: /* not supported */ default: - DPRINTK(PROBE, ERR, - "Unsupported Speed/Duplexity configuration\n"); + DPRINTK(PROBE, ERR, "Unsupported Speed/Duplex configuration\n"); return -EINVAL; } return 0; @@ -3810,7 +3785,7 @@ e1000_resume(struct pci_dev *pdev) * the interrupt routine is executing. */ static void -e1000_netpoll (struct net_device *netdev) +e1000_netpoll(struct net_device *netdev) { struct e1000_adapter *adapter = netdev->priv; disable_irq(adapter->pdev->irq); diff --git a/drivers/net/e1000/e1000_osdep.h b/drivers/net/e1000/e1000_osdep.h index b1915e8eb564..aac64de61437 100644 --- a/drivers/net/e1000/e1000_osdep.h +++ b/drivers/net/e1000/e1000_osdep.h @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c index e914d09fe6f9..676247f9f1cc 100644 --- a/drivers/net/e1000/e1000_param.c +++ b/drivers/net/e1000/e1000_param.c @@ -1,7 +1,7 @@ /******************************************************************************* - Copyright(c) 1999 - 2004 Intel Corporation. All rights reserved. + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -478,7 +478,6 @@ e1000_check_options(struct e1000_adapter *adapter) DPRINTK(PROBE, INFO, "%s set to dynamic mode\n", opt.name); break; - case -1: default: e1000_validate_option(&adapter->itr, &opt, adapter); -- cgit v1.2.2 From 5633684d008b777ab169e8efcef39a898482f531 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 18:45:50 -0700 Subject: [PATCH] ixgb: Fix multi-cast packet count in statistics Fix multi-cast packet count in statistics Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 7d26623d8592..1498b4e42466 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1526,14 +1526,33 @@ ixgb_change_mtu(struct net_device *netdev, int new_mtu) void ixgb_update_stats(struct ixgb_adapter *adapter) { + struct net_device *netdev = adapter->netdev; + + if((netdev->flags & IFF_PROMISC) || (netdev->flags & IFF_ALLMULTI) || + (netdev->mc_count > IXGB_MAX_NUM_MULTICAST_ADDRESSES)) { + u64 multi = IXGB_READ_REG(&adapter->hw, MPRCL); + u32 bcast_l = IXGB_READ_REG(&adapter->hw, BPRCL); + u32 bcast_h = IXGB_READ_REG(&adapter->hw, BPRCH); + u64 bcast = ((u64)bcast_h << 32) | bcast_l; + + multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32); + /* fix up multicast stats by removing broadcasts */ + multi -= bcast; + + adapter->stats.mprcl += (multi & 0xFFFFFFFF); + adapter->stats.mprch += (multi >> 32); + adapter->stats.bprcl += bcast_l; + adapter->stats.bprch += bcast_h; + } else { + adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL); + adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH); + adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL); + adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH); + } adapter->stats.tprl += IXGB_READ_REG(&adapter->hw, TPRL); adapter->stats.tprh += IXGB_READ_REG(&adapter->hw, TPRH); adapter->stats.gprcl += IXGB_READ_REG(&adapter->hw, GPRCL); adapter->stats.gprch += IXGB_READ_REG(&adapter->hw, GPRCH); - adapter->stats.bprcl += IXGB_READ_REG(&adapter->hw, BPRCL); - adapter->stats.bprch += IXGB_READ_REG(&adapter->hw, BPRCH); - adapter->stats.mprcl += IXGB_READ_REG(&adapter->hw, MPRCL); - adapter->stats.mprch += IXGB_READ_REG(&adapter->hw, MPRCH); adapter->stats.uprcl += IXGB_READ_REG(&adapter->hw, UPRCL); adapter->stats.uprch += IXGB_READ_REG(&adapter->hw, UPRCH); adapter->stats.vprcl += IXGB_READ_REG(&adapter->hw, VPRCL); -- cgit v1.2.2 From 06c2f9ecb5b53f9d4fc1ef596da16683cc4af5ba Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 18:46:51 -0700 Subject: [PATCH] ixgb: Do not set the RS bit on context descriptors Don't set the RS bit on context descriptors, causes un-necessary bus activity Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 1498b4e42466..364a9e78b0cc 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1209,10 +1209,10 @@ ixgb_tso(struct ixgb_adapter *adapter, struct sk_buff *skb) | IXGB_CONTEXT_DESC_CMD_TSE | IXGB_CONTEXT_DESC_CMD_IP | IXGB_CONTEXT_DESC_CMD_TCP - | IXGB_CONTEXT_DESC_CMD_RS | IXGB_CONTEXT_DESC_CMD_IDE | (skb->len - (hdr_len))); + if(++i == adapter->tx_ring.count) i = 0; adapter->tx_ring.next_to_use = i; @@ -1247,8 +1247,7 @@ ixgb_tx_csum(struct ixgb_adapter *adapter, struct sk_buff *skb) context_desc->mss = 0; context_desc->cmd_type_len = cpu_to_le32(IXGB_CONTEXT_DESC_TYPE - | IXGB_TX_DESC_CMD_RS - | IXGB_TX_DESC_CMD_IDE); + | IXGB_TX_DESC_CMD_IDE); if(++i == adapter->tx_ring.count) i = 0; adapter->tx_ring.next_to_use = i; -- cgit v1.2.2 From 0c73f58636385a4d3dc68d0d0829d4c39d61b621 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 18:48:06 -0700 Subject: [PATCH] ixgb: Change RDT write bump size to 4 Change RDT write bump size back to 4 Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb.h net-drivers-2.6/drivers/net/ixgb.new/ixgb.h --- drivers/net/ixgb/ixgb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index 26c4f15f7fc0..f8d3385c7842 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h @@ -110,7 +110,7 @@ struct ixgb_adapter; #define IXGB_TX_QUEUE_WAKE 16 /* How many Rx Buffers do we bundle into one write to the hardware ? */ -#define IXGB_RX_BUFFER_WRITE 16 /* Must be power of 2 */ +#define IXGB_RX_BUFFER_WRITE 4 /* Must be power of 2 */ /* only works for sizes that are powers of 2 */ #define IXGB_ROUNDUP(i, size) ((i) = (((i) + (size) - 1) & ~((size) - 1))) -- cgit v1.2.2 From 6dfbb6dd391139be9f1cd333877c6e2b03da4bba Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 18:56:40 -0700 Subject: [PATCH] ixgb: Mask RXO interrupt Disable RXO interrupt to decrease recovery time when system is overloaded with data Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 364a9e78b0cc..da6b9d6e6db9 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -224,8 +224,8 @@ ixgb_irq_enable(struct ixgb_adapter *adapter) { if(atomic_dec_and_test(&adapter->irq_sem)) { IXGB_WRITE_REG(&adapter->hw, IMS, - IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW | - IXGB_INT_RXO | IXGB_INT_LSC); + IXGB_INT_RXT0 | IXGB_INT_RXDMT0 | IXGB_INT_TXDW | + IXGB_INT_LSC); IXGB_WRITE_FLUSH(&adapter->hw); } } -- cgit v1.2.2 From 41639fed1b32dde4ea3d94242a89308435d341be Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 18:51:54 -0700 Subject: [PATCH] ixgb: Reset status in the Rx Reset status in the Rx descriptor prior to handing it to the controller. Leave three Rx descriptors unused Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index da6b9d6e6db9..a6a13f6fe65b 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1977,8 +1977,8 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) num_group_tail_writes = IXGB_RX_BUFFER_WRITE; - /* leave one descriptor unused */ - while(--cleancount > 0) { + /* leave three descriptors unused */ + while(--cleancount > 2) { rx_desc = IXGB_RX_DESC(*rx_ring, i); skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN); @@ -2005,6 +2005,10 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) PCI_DMA_FROMDEVICE); rx_desc->buff_addr = cpu_to_le64(buffer_info->dma); + /* guarantee DD bit not set now before h/w gets descriptor + * this is the rest of the workaround for h/w double + * writeback. */ + rx_desc->status = 0; if((i & ~(num_group_tail_writes- 1)) == i) { /* Force memory writes to complete before letting h/w -- cgit v1.2.2 From abf481d6af8670c89f33f354c6fbd9977b23cebc Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:03:32 -0700 Subject: [PATCH] ixgb: Fix EEPROM functions to be endian-aware Fix EEPROM functions to be endian-aware Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_ee.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_ee.c --- drivers/net/ixgb/ixgb_ee.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index 653e99f919ce..3aae110c5560 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c @@ -411,7 +411,7 @@ ixgb_write_eeprom(struct ixgb_hw *hw, uint16_t offset, uint16_t data) ixgb_cleanup_eeprom(hw); /* clear the init_ctrl_reg_1 to signify that the cache is invalidated */ - ee_map->init_ctrl_reg_1 = EEPROM_ICW1_SIGNATURE_CLEAR; + ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR); return; } @@ -483,7 +483,7 @@ ixgb_get_eeprom_data(struct ixgb_hw *hw) DEBUGOUT("ixgb_ee: Checksum invalid.\n"); /* clear the init_ctrl_reg_1 to signify that the cache is * invalidated */ - ee_map->init_ctrl_reg_1 = EEPROM_ICW1_SIGNATURE_CLEAR; + ee_map->init_ctrl_reg_1 = le16_to_cpu(EEPROM_ICW1_SIGNATURE_CLEAR); return (FALSE); } @@ -579,7 +579,7 @@ ixgb_get_ee_compatibility(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->compatibility); + return (le16_to_cpu(ee_map->compatibility)); return(0); } @@ -616,7 +616,7 @@ ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->init_ctrl_reg_1); + return (le16_to_cpu(ee_map->init_ctrl_reg_1)); return(0); } @@ -635,7 +635,7 @@ ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->init_ctrl_reg_2); + return (le16_to_cpu(ee_map->init_ctrl_reg_2)); return(0); } @@ -654,7 +654,7 @@ ixgb_get_ee_subsystem_id(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->subsystem_id); + return (le16_to_cpu(ee_map->subsystem_id)); return(0); } @@ -673,7 +673,7 @@ ixgb_get_ee_subvendor_id(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->subvendor_id); + return (le16_to_cpu(ee_map->subvendor_id)); return(0); } @@ -692,7 +692,7 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->device_id); + return (le16_to_cpu(ee_map->device_id)); return(0); } @@ -711,7 +711,7 @@ ixgb_get_ee_vendor_id(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->vendor_id); + return (le16_to_cpu(ee_map->vendor_id)); return(0); } @@ -730,7 +730,7 @@ ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->swdpins_reg); + return (le16_to_cpu(ee_map->swdpins_reg)); return(0); } @@ -749,7 +749,7 @@ ixgb_get_ee_d3_power(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->d3_power); + return (le16_to_cpu(ee_map->d3_power)); return(0); } @@ -768,7 +768,7 @@ ixgb_get_ee_d0_power(struct ixgb_hw *hw) struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; if(ixgb_check_and_get_eeprom_data(hw) == TRUE) - return(ee_map->d0_power); + return (le16_to_cpu(ee_map->d0_power)); return(0); } -- cgit v1.2.2 From 5e3c30deb21d0eb0da44830fb1c1fc7054e54229 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:04:07 -0700 Subject: [PATCH] ixgb: Support for ethtool -d ixgb support for ethtool -d Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_ethtool.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_ethtool.c --- drivers/net/ixgb/ixgb_ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index aea10e8aaa72..3fa113854eeb 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c @@ -252,7 +252,9 @@ ixgb_get_regs(struct net_device *netdev, uint32_t *reg_start = reg; uint8_t i; - regs->version = (adapter->hw.device_id << 16) | adapter->hw.subsystem_id; + /* the 1 (one) below indicates an attempt at versioning, if the + * interface in ethtool or the driver this 1 should be incremented */ + regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; /* General Registers */ *reg++ = IXGB_READ_REG(hw, CTRL0); /* 0 */ -- cgit v1.2.2 From c2eba932b14718e34ac2609e35c6d41e032a2478 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:04:32 -0700 Subject: [PATCH] ixgb: Remove hook for suspend, no power management Remove hook for suspend. No power management in 10GbE Controllers Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 75 +++----------------------------------------- 1 file changed, 4 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index a6a13f6fe65b..0a0f0417f85d 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -120,33 +120,20 @@ static void ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid); static void ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid); static void ixgb_restore_vlan(struct ixgb_adapter *adapter); -static int ixgb_notify_reboot(struct notifier_block *, unsigned long event, - void *ptr); -static int ixgb_suspend(struct pci_dev *pdev, uint32_t state); - #ifdef CONFIG_NET_POLL_CONTROLLER /* for netdump / net console */ static void ixgb_netpoll(struct net_device *dev); #endif -struct notifier_block ixgb_notifier_reboot = { - .notifier_call = ixgb_notify_reboot, - .next = NULL, - .priority = 0 -}; - /* Exported from other modules */ extern void ixgb_check_options(struct ixgb_adapter *adapter); static struct pci_driver ixgb_driver = { - .name = ixgb_driver_name, + .name = ixgb_driver_name, .id_table = ixgb_pci_tbl, - .probe = ixgb_probe, - .remove = __devexit_p(ixgb_remove), - /* Power Managment Hooks */ - .suspend = NULL, - .resume = NULL + .probe = ixgb_probe, + .remove = __devexit_p(ixgb_remove), }; MODULE_AUTHOR("Intel Corporation, "); @@ -169,17 +156,12 @@ MODULE_LICENSE("GPL"); static int __init ixgb_init_module(void) { - int ret; printk(KERN_INFO "%s - version %s\n", ixgb_driver_string, ixgb_driver_version); printk(KERN_INFO "%s\n", ixgb_copyright); - ret = pci_module_init(&ixgb_driver); - if(ret >= 0) { - register_reboot_notifier(&ixgb_notifier_reboot); - } - return ret; + return pci_module_init(&ixgb_driver); } module_init(ixgb_init_module); @@ -194,7 +176,6 @@ module_init(ixgb_init_module); static void __exit ixgb_exit_module(void) { - unregister_reboot_notifier(&ixgb_notifier_reboot); pci_unregister_driver(&ixgb_driver); } @@ -2121,54 +2102,6 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) } } -/** - * ixgb_notify_reboot - handles OS notification of reboot event. - * @param nb notifier block, unused - * @param event Event being passed to driver to act upon - * @param p A pointer to our net device - **/ -static int -ixgb_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) -{ - struct pci_dev *pdev = NULL; - - switch(event) { - case SYS_DOWN: - case SYS_HALT: - case SYS_POWER_OFF: - while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { - if (pci_dev_driver(pdev) == &ixgb_driver) - ixgb_suspend(pdev, 3); - } - } - return NOTIFY_DONE; -} - -/** - * ixgb_suspend - driver suspend function called from notify. - * @param pdev pci driver structure used for passing to - * @param state power state to enter - **/ -static int -ixgb_suspend(struct pci_dev *pdev, uint32_t state) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgb_adapter *adapter = netdev->priv; - - netif_device_detach(netdev); - - if(netif_running(netdev)) - ixgb_down(adapter, TRUE); - - pci_save_state(pdev); - - state = (state > 0) ? 3 : 0; - pci_set_power_state(pdev, state); - msec_delay(200); - - return 0; -} - #ifdef CONFIG_NET_POLL_CONTROLLER /* * Polling 'interrupt' - used by things like netconsole to send skbs -- cgit v1.2.2 From f404de1cd407c1f56fa478810c6c48e015d377bd Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:04:54 -0700 Subject: [PATCH] ixgb: Code optimization Code optimization Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 0a0f0417f85d..db1089c67ebc 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -1822,7 +1822,6 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) struct pci_dev *pdev = adapter->pdev; struct ixgb_rx_desc *rx_desc, *next_rxd; struct ixgb_buffer *buffer_info, *next_buffer, *next2_buffer; - struct sk_buff *skb, *next_skb; uint32_t length; unsigned int i, j; boolean_t cleaned = FALSE; @@ -1832,6 +1831,8 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) buffer_info = &rx_ring->buffer_info[i]; while(rx_desc->status & IXGB_RX_DESC_STATUS_DD) { + struct sk_buff *skb, *next_skb; + u8 status; #ifdef CONFIG_IXGB_NAPI if(*work_done >= work_to_do) @@ -1839,7 +1840,9 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) (*work_done)++; #endif + status = rx_desc->status; skb = buffer_info->skb; + prefetch(skb->data); if(++i == rx_ring->count) i = 0; @@ -1864,7 +1867,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) length = le16_to_cpu(rx_desc->length); - if(unlikely(!(rx_desc->status & IXGB_RX_DESC_STATUS_EOP))) { + if(unlikely(!(status & IXGB_RX_DESC_STATUS_EOP))) { /* All receives must fit into a single buffer */ @@ -1872,12 +1875,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) "length<%x>\n", length); dev_kfree_skb_irq(skb); - rx_desc->status = 0; - buffer_info->skb = NULL; - - rx_desc = next_rxd; - buffer_info = next_buffer; - continue; + goto rxdesc_done; } if (unlikely(rx_desc->errors @@ -1886,12 +1884,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) IXGB_RX_DESC_ERRORS_RXE))) { dev_kfree_skb_irq(skb); - rx_desc->status = 0; - buffer_info->skb = NULL; - - rx_desc = next_rxd; - buffer_info = next_buffer; - continue; + goto rxdesc_done; } /* Good Receive */ @@ -1902,7 +1895,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) skb->protocol = eth_type_trans(skb, netdev); #ifdef CONFIG_IXGB_NAPI - if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) { + if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) { vlan_hwaccel_receive_skb(skb, adapter->vlgrp, le16_to_cpu(rx_desc->special) & IXGB_RX_DESC_SPECIAL_VLAN_MASK); @@ -1910,7 +1903,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) netif_receive_skb(skb); } #else /* CONFIG_IXGB_NAPI */ - if(adapter->vlgrp && (rx_desc->status & IXGB_RX_DESC_STATUS_VP)) { + if(adapter->vlgrp && (status & IXGB_RX_DESC_STATUS_VP)) { vlan_hwaccel_rx(skb, adapter->vlgrp, le16_to_cpu(rx_desc->special) & IXGB_RX_DESC_SPECIAL_VLAN_MASK); @@ -1920,9 +1913,12 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) #endif /* CONFIG_IXGB_NAPI */ netdev->last_rx = jiffies; +rxdesc_done: + /* clean up descriptor, might be written over by hw */ rx_desc->status = 0; buffer_info->skb = NULL; + /* use prefetched values */ rx_desc = next_rxd; buffer_info = next_buffer; } -- cgit v1.2.2 From 37d16f823799918107440cb9e552b0709347f77c Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:05:12 -0700 Subject: [PATCH] ixgb: Fixed msec_delay in osdep to use msleep Fixed msec_delay in osdep to use msleep Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_osdep.h net-drivers-2.6/drivers/net/ixgb.new/ixgb_osdep.h --- drivers/net/ixgb/ixgb_osdep.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h index 9eba92891901..dba20481ee80 100644 --- a/drivers/net/ixgb/ixgb_osdep.h +++ b/drivers/net/ixgb/ixgb_osdep.h @@ -45,8 +45,7 @@ /* Don't mdelay in interrupt context! */ \ BUG(); \ } else { \ - set_current_state(TASK_UNINTERRUPTIBLE); \ - schedule_timeout((x * HZ)/1000 + 2); \ + msleep(x); \ } } while(0) #endif -- cgit v1.2.2 From ac79c82e793bc2440c4765e5eb1b834d2c18edf2 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:05:32 -0700 Subject: [PATCH] ixgb: Driver version, white space, comments, device id Driver version, white space, comments, device id & other Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak diff -up net-drivers-2.6/drivers/net/ixgb/ixgb_main.c net-drivers-2.6/drivers/net/ixgb.new/ixgb_main.c --- drivers/net/ixgb/ixgb_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index db1089c67ebc..35f6a7c271a2 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c @@ -47,7 +47,7 @@ char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -char ixgb_driver_version[] = "1.0.90-k2"DRIVERNAPI; +char ixgb_driver_version[] = "1.0.95-k2"DRIVERNAPI; char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; /* ixgb_pci_tbl - PCI Device ID Table @@ -103,6 +103,7 @@ static int ixgb_change_mtu(struct net_device *netdev, int new_mtu); static int ixgb_set_mac(struct net_device *netdev, void *p); static irqreturn_t ixgb_intr(int irq, void *data, struct pt_regs *regs); static boolean_t ixgb_clean_tx_irq(struct ixgb_adapter *adapter); + #ifdef CONFIG_IXGB_NAPI static int ixgb_clean(struct net_device *netdev, int *budget); static boolean_t ixgb_clean_rx_irq(struct ixgb_adapter *adapter, @@ -1253,6 +1254,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb, unsigned int nr_frags = skb_shinfo(skb)->nr_frags; unsigned int f; + len -= skb->data_len; i = tx_ring->next_to_use; @@ -1857,7 +1859,6 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter) next_skb = next_buffer->skb; prefetch(next_skb); - cleaned = TRUE; pci_unmap_single(pdev, @@ -2108,6 +2109,7 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter) static void ixgb_netpoll(struct net_device *dev) { struct ixgb_adapter *adapter = dev->priv; + disable_irq(adapter->pdev->irq); ixgb_intr(adapter->pdev->irq, dev, NULL); enable_irq(adapter->pdev->irq); -- cgit v1.2.2 From 2acdb1e05c1a92e05ee710ed8f226a8f3183d5a0 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:16:58 -0700 Subject: [PATCH] e100: Execute tx_timeout task outside interrupt context Execute tx_timeout task outside the interrupt context Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak --- drivers/net/e100.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 1b68dd5a49b6..0f2837ebaab8 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -539,6 +539,7 @@ struct nic { struct timer_list watchdog; struct timer_list blink_timer; struct mii_if_info mii; + struct work_struct tx_timeout_task; enum loopback loopback; struct mem *mem; @@ -1716,6 +1717,15 @@ static void e100_tx_timeout(struct net_device *netdev) { struct nic *nic = netdev_priv(netdev); + /* Reset outside of interrupt context, to avoid request_irq + * in interrupt context */ + schedule_work(&nic->tx_timeout_task); +} + +static void e100_tx_timeout_task(struct net_device *netdev) +{ + struct nic *nic = netdev_priv(netdev); + DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n", readb(&nic->csr->scb.status)); e100_down(netdev_priv(netdev)); @@ -2240,6 +2250,9 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->blink_timer.function = e100_blink_led; nic->blink_timer.data = (unsigned long)nic; + INIT_WORK(&nic->tx_timeout_task, + (void (*)(void *))e100_tx_timeout_task, netdev); + if((err = e100_alloc(nic))) { DPRINTK(PROBE, ERR, "Cannot alloc driver memory, aborting.\n"); goto err_out_iounmap; -- cgit v1.2.2 From 1f53367d5d75ba37f258f6e955d6fc24814051a0 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:17:20 -0700 Subject: [PATCH] e100: Render e100 NAPI state machine Render e100 NAPI state machine to be similar to the non-NAPI one. Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak --- drivers/net/e100.c | 86 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 0f2837ebaab8..2c8c14ebf205 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -269,6 +269,12 @@ enum scb_status { rus_mask = 0x3C, }; +enum ru_state { + RU_SUSPENDED = 0, + RU_RUNNING = 1, + RU_UNINITIALIZED = -1, +}; + enum scb_stat_ack { stat_ack_not_ours = 0x00, stat_ack_sw_gen = 0x04, @@ -510,7 +516,7 @@ struct nic { struct rx *rx_to_use; struct rx *rx_to_clean; struct rfd blank_rfd; - int ru_running; + enum ru_state ru_running; spinlock_t cb_lock ____cacheline_aligned; spinlock_t cmd_lock; @@ -1204,7 +1210,9 @@ static void e100_update_stats(struct nic *nic) } } - e100_exec_cmd(nic, cuc_dump_reset, 0); + + if(e100_exec_cmd(nic, cuc_dump_reset, 0)) + DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n"); } static void e100_adjust_adaptive_ifs(struct nic *nic, int speed, int duplex) @@ -1298,7 +1306,8 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* SW workaround for ICH[x] 10Mbps/half duplex Tx hang. Issue a NOP command followed by a 1us delay before issuing the Tx command. */ - e100_exec_cmd(nic, cuc_nop, 0); + if(e100_exec_cmd(nic, cuc_nop, 0)) + DPRINTK(TX_ERR, DEBUG, "exec cuc_nop failed\n"); udelay(1); } @@ -1416,12 +1425,18 @@ static int e100_alloc_cbs(struct nic *nic) return 0; } -static inline void e100_start_receiver(struct nic *nic) +static inline void e100_start_receiver(struct nic *nic, struct rx *rx) { + if(!nic->rxs) return; + if(RU_SUSPENDED != nic->ru_running) return; + + /* handle init time starts */ + if(!rx) rx = nic->rxs; + /* (Re)start RU if suspended or idle and RFA is non-NULL */ - if(!nic->ru_running && nic->rx_to_clean->skb) { - e100_exec_cmd(nic, ruc_start, nic->rx_to_clean->dma_addr); - nic->ru_running = 1; + if(rx->skb) { + e100_exec_cmd(nic, ruc_start, rx->dma_addr); + nic->ru_running = RU_RUNNING; } } @@ -1438,6 +1453,13 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx) rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data, RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL); + if(pci_dma_mapping_error(rx->dma_addr)) { + dev_kfree_skb_any(rx->skb); + rx->skb = 0; + rx->dma_addr = 0; + return -ENOMEM; + } + /* Link the RFD to end of RFA by linking previous RFD to * this one, and clearing EL bit of previous. */ if(rx->prev->skb) { @@ -1472,7 +1494,7 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx, /* If data isn't ready, nothing to indicate */ if(unlikely(!(rfd_status & cb_complete))) - return -EAGAIN; + return -ENODATA; /* Get actual data size */ actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF; @@ -1483,6 +1505,10 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx, pci_unmap_single(nic->pdev, rx->dma_addr, RFD_BUF_LEN, PCI_DMA_FROMDEVICE); + /* this allows for a fast restart without re-enabling interrupts */ + if(le16_to_cpu(rfd->command) & cb_el) + nic->ru_running = RU_SUSPENDED; + /* Pull off the RFD and put the actual data (minus eth hdr) */ skb_reserve(skb, sizeof(struct rfd)); skb_put(skb, actual_size); @@ -1515,20 +1541,45 @@ static inline void e100_rx_clean(struct nic *nic, unsigned int *work_done, unsigned int work_to_do) { struct rx *rx; + int restart_required = 0; + struct rx *rx_to_start = NULL; + + /* are we already rnr? then pay attention!!! this ensures that + * the state machine progression never allows a start with a + * partially cleaned list, avoiding a race between hardware + * and rx_to_clean when in NAPI mode */ + if(RU_SUSPENDED == nic->ru_running) + restart_required = 1; /* Indicate newly arrived packets */ for(rx = nic->rx_to_clean; rx->skb; rx = nic->rx_to_clean = rx->next) { - if(e100_rx_indicate(nic, rx, work_done, work_to_do)) + int err = e100_rx_indicate(nic, rx, work_done, work_to_do); + if(-EAGAIN == err) { + /* hit quota so have more work to do, restart once + * cleanup is complete */ + restart_required = 0; + break; + } else if(-ENODATA == err) break; /* No more to clean */ } + /* save our starting point as the place we'll restart the receiver */ + if(restart_required) + rx_to_start = nic->rx_to_clean; + /* Alloc new skbs to refill list */ for(rx = nic->rx_to_use; !rx->skb; rx = nic->rx_to_use = rx->next) { if(unlikely(e100_rx_alloc_skb(nic, rx))) break; /* Better luck next time (see watchdog) */ } - e100_start_receiver(nic); + if(restart_required) { + // ack the rnr? + writeb(stat_ack_rnr, &nic->csr->scb.stat_ack); + e100_start_receiver(nic, rx_to_start); + if(work_done) + (*work_done)++; + } } static void e100_rx_clean_list(struct nic *nic) @@ -1536,6 +1587,8 @@ static void e100_rx_clean_list(struct nic *nic) struct rx *rx; unsigned int i, count = nic->params.rfds.count; + nic->ru_running = RU_UNINITIALIZED; + if(nic->rxs) { for(rx = nic->rxs, i = 0; i < count; rx++, i++) { if(rx->skb) { @@ -1549,7 +1602,6 @@ static void e100_rx_clean_list(struct nic *nic) } nic->rx_to_use = nic->rx_to_clean = NULL; - nic->ru_running = 0; } static int e100_rx_alloc_list(struct nic *nic) @@ -1558,6 +1610,7 @@ static int e100_rx_alloc_list(struct nic *nic) unsigned int i, count = nic->params.rfds.count; nic->rx_to_use = nic->rx_to_clean = NULL; + nic->ru_running = RU_UNINITIALIZED; if(!(nic->rxs = kmalloc(sizeof(struct rx) * count, GFP_ATOMIC))) return -ENOMEM; @@ -1573,6 +1626,7 @@ static int e100_rx_alloc_list(struct nic *nic) } nic->rx_to_use = nic->rx_to_clean = nic->rxs; + nic->ru_running = RU_SUSPENDED; return 0; } @@ -1594,7 +1648,7 @@ static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs) /* We hit Receive No Resource (RNR); restart RU after cleaning */ if(stat_ack & stat_ack_rnr) - nic->ru_running = 0; + nic->ru_running = RU_SUSPENDED; e100_disable_irq(nic); netif_rx_schedule(netdev); @@ -1684,7 +1738,7 @@ static int e100_up(struct nic *nic) if((err = e100_hw_init(nic))) goto err_clean_cbs; e100_set_multicast_list(nic->netdev); - e100_start_receiver(nic); + e100_start_receiver(nic, 0); mod_timer(&nic->watchdog, jiffies); if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, nic->netdev->name, nic->netdev))) @@ -1759,7 +1813,7 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode) mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, BMCR_LOOPBACK); - e100_start_receiver(nic); + e100_start_receiver(nic, 0); if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) { err = -ENOMEM; @@ -2233,6 +2287,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, e100_get_defaults(nic); + /* locks must be initialized before calling hw_reset */ spin_lock_init(&nic->cb_lock); spin_lock_init(&nic->cmd_lock); @@ -2348,7 +2403,8 @@ static int e100_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); - e100_hw_init(nic); + if(e100_hw_init(nic)) + DPRINTK(HW, ERR, "e100_hw_init failed\n"); netif_device_attach(netdev); if(netif_running(netdev)) -- cgit v1.2.2 From 0236ebb7ae85935b3b96eef7e8a4e203ea9958a0 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:17:42 -0700 Subject: [PATCH] e100: Synchronize interface link state with poll routine Synchronize interface link state with e100 poll routine Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak --- drivers/net/e100.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 2c8c14ebf205..c1ca2dae7c48 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -1743,8 +1743,11 @@ static int e100_up(struct nic *nic) if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ, nic->netdev->name, nic->netdev))) goto err_no_irq; - e100_enable_irq(nic); netif_wake_queue(nic->netdev); + netif_poll_enable(nic->netdev); + /* enable ints _after_ enabling poll, preventing a race between + * disable ints+schedule */ + e100_enable_irq(nic); return 0; err_no_irq: @@ -1758,11 +1761,13 @@ err_rx_clean_list: static void e100_down(struct nic *nic) { + /* wait here for poll to complete */ + netif_poll_disable(nic->netdev); + netif_stop_queue(nic->netdev); e100_hw_reset(nic); free_irq(nic->pdev->irq, nic->netdev); del_timer_sync(&nic->watchdog); netif_carrier_off(nic->netdev); - netif_stop_queue(nic->netdev); e100_clean_cbs(nic); e100_rx_clean_list(nic); } -- cgit v1.2.2 From 6bdacb1ad58bb6b772a4fc18f21684437bd5f439 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:17:54 -0700 Subject: [PATCH] e100: Fix Wake on lan related issues Fix Wake on lan related issues Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak --- drivers/net/e100.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index c1ca2dae7c48..a43b82512b60 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -971,7 +971,8 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) if(nic->flags & multicast_all) config->multicast_all = 0x1; /* 1=accept, 0=no */ - if(!(nic->flags & wol_magic)) + /* disable WoL when up */ + if(netif_running(nic->netdev) || !(nic->flags & wol_magic)) config->magic_packet_disable = 0x1; /* 1=off, 0=on */ if(nic->mac >= mac_82558_D101_A4) { @@ -1718,6 +1719,7 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu) return 0; } +#ifdef CONFIG_PM static int e100_asf(struct nic *nic) { /* ASF can be enabled from eeprom */ @@ -1726,6 +1728,7 @@ static int e100_asf(struct nic *nic) !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) && ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE)); } +#endif static int e100_up(struct nic *nic) { @@ -1938,7 +1941,6 @@ static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) else nic->flags &= ~wol_magic; - pci_enable_wake(nic->pdev, 0, nic->flags & (wol_magic | e100_asf(nic))); e100_exec_cb(nic, NULL, e100_configure); return 0; @@ -2336,7 +2338,8 @@ static int __devinit e100_probe(struct pci_dev *pdev, (nic->eeprom[eeprom_id] & eeprom_id_wol)) nic->flags |= wol_magic; - pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic))); + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, 0, 0); strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) { @@ -2408,6 +2411,8 @@ static int e100_resume(struct pci_dev *pdev) pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, 0, 0); if(e100_hw_init(nic)) DPRINTK(HW, ERR, "e100_hw_init failed\n"); @@ -2419,6 +2424,21 @@ static int e100_resume(struct pci_dev *pdev) } #endif + +static void e100_shutdown(struct device *dev) +{ + struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); + struct net_device *netdev = pci_get_drvdata(pdev); + struct nic *nic = netdev_priv(netdev); + +#ifdef CONFIG_PM + pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic))); +#else + pci_enable_wake(pdev, 0, nic->flags & (wol_magic)); +#endif +} + + static struct pci_driver e100_driver = { .name = DRV_NAME, .id_table = e100_id_table, @@ -2428,6 +2448,11 @@ static struct pci_driver e100_driver = { .suspend = e100_suspend, .resume = e100_resume, #endif + + .driver = { + .shutdown = e100_shutdown, + } + }; static int __init e100_init_module(void) -- cgit v1.2.2 From 962082b6df11fe8cabafd2971b07c914cd52ee2a Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:19:46 -0700 Subject: [PATCH] e100: Performance optimizations to e100 Tx Path Performance optimizations to e100 Tx Path Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak --- drivers/net/e100.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index a43b82512b60..fc2a401d561d 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -777,7 +777,7 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count) return 0; } -#define E100_WAIT_SCB_TIMEOUT 40 +#define E100_WAIT_SCB_TIMEOUT 20000 /* we might have to wait 100ms!!! */ static inline int e100_exec_cmd(struct nic *nic, u8 cmd, dma_addr_t dma_addr) { unsigned long flags; @@ -847,6 +847,10 @@ static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb, * because the controller is too busy, so * let's just queue the command and try again * when another command is scheduled. */ + if(err == -ENOSPC) { + //request a reset + schedule_work(&nic->tx_timeout_task); + } break; } else { nic->cuc_cmd = cuc_resume; @@ -891,7 +895,7 @@ static void mdio_write(struct net_device *netdev, int addr, int reg, int data) static void e100_get_defaults(struct nic *nic) { - struct param_range rfds = { .min = 64, .max = 256, .count = 64 }; + struct param_range rfds = { .min = 16, .max = 256, .count = 64 }; struct param_range cbs = { .min = 64, .max = 256, .count = 64 }; pci_read_config_byte(nic->pdev, PCI_REVISION_ID, &nic->rev_id); @@ -906,8 +910,9 @@ static void e100_get_defaults(struct nic *nic) /* Quadwords to DMA into FIFO before starting frame transmit */ nic->tx_threshold = 0xE0; - nic->tx_command = cpu_to_le16(cb_tx | cb_i | cb_tx_sf | - ((nic->mac >= mac_82558_D101_A4) ? cb_cid : 0)); + /* no interrupt for every tx completion, delay = 256us if not 557*/ + nic->tx_command = cpu_to_le16(cb_tx | cb_tx_sf | + ((nic->mac >= mac_82558_D101_A4) ? cb_cid : cb_i)); /* Template for a freshly allocated RFD */ nic->blank_rfd.command = cpu_to_le16(cb_el); @@ -1289,12 +1294,15 @@ static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb, struct sk_buff *skb) { cb->command = nic->tx_command; + /* interrupt every 16 packets regardless of delay */ + if((nic->cbs_avail & ~15) == nic->cbs_avail) cb->command |= cb_i; cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd); cb->u.tcb.tcb_byte_count = 0; cb->u.tcb.threshold = nic->tx_threshold; cb->u.tcb.tbd_count = 1; cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev, skb->data, skb->len, PCI_DMA_TODEVICE)); + // check for mapping failure? cb->u.tcb.tbd.size = cpu_to_le16(skb->len); } -- cgit v1.2.2 From 042e2fb70006f135469d546726451b7d14768980 Mon Sep 17 00:00:00 2001 From: Malli Chilakala Date: Thu, 28 Apr 2005 19:20:14 -0700 Subject: [PATCH] e100: Driver version, white space, comments, device id Driver version, white space, comments. Also enabled ICH-7 support Signed-off-by: Mallikarjuna R Chilakala Signed-off-by: Ganesh Venkatesan Signed-off-by: John Ronciak --- drivers/net/e100.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/e100.c b/drivers/net/e100.c index fc2a401d561d..4a47df5a9ff9 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -155,9 +155,9 @@ #define DRV_NAME "e100" #define DRV_EXT "-NAPI" -#define DRV_VERSION "3.3.6-k2"DRV_EXT +#define DRV_VERSION "3.4.8-k2"DRV_EXT #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" -#define DRV_COPYRIGHT "Copyright(c) 1999-2004 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" #define PFX DRV_NAME ": " #define E100_WATCHDOG_PERIOD (2 * HZ) @@ -210,11 +210,17 @@ static struct pci_device_id e100_id_table[] = { INTEL_8255X_ETHERNET_DEVICE(0x1069, 6), INTEL_8255X_ETHERNET_DEVICE(0x106A, 6), INTEL_8255X_ETHERNET_DEVICE(0x106B, 6), + INTEL_8255X_ETHERNET_DEVICE(0x1091, 7), + INTEL_8255X_ETHERNET_DEVICE(0x1092, 7), + INTEL_8255X_ETHERNET_DEVICE(0x1093, 7), + INTEL_8255X_ETHERNET_DEVICE(0x1094, 7), + INTEL_8255X_ETHERNET_DEVICE(0x1095, 7), INTEL_8255X_ETHERNET_DEVICE(0x1209, 0), INTEL_8255X_ETHERNET_DEVICE(0x1229, 0), INTEL_8255X_ETHERNET_DEVICE(0x2449, 2), INTEL_8255X_ETHERNET_DEVICE(0x2459, 2), INTEL_8255X_ETHERNET_DEVICE(0x245D, 2), + INTEL_8255X_ETHERNET_DEVICE(0x27DC, 7), { 0, } }; MODULE_DEVICE_TABLE(pci, e100_id_table); -- cgit v1.2.2 From 321de3c8cc12bdff073c23524aa1f6ed47cbeee4 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:17:46 +0200 Subject: [PATCH] s390: claw driver wiring [patch 1/10] s390: claw driver wiring. From: Andy Richter claw network driver changes: - Add an entry to the drivers/s390/net Makefile to build the claw driver. - Add claw channel type to cu3088. Signed-off-by: Frank Pavlic --- drivers/s390/net/Makefile | 1 + drivers/s390/net/cu3088.c | 4 +++- drivers/s390/net/cu3088.h | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile index 7cabb80a2e41..85b590c5701d 100644 --- a/drivers/s390/net/Makefile +++ b/drivers/s390/net/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o obj-$(CONFIG_SMSGIUCV) += smsgiucv.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o obj-$(CONFIG_LCS) += lcs.o cu3088.o +obj-$(CONFIG_CLAW) += claw.o cu3088.o qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth_tso.o qeth-$(CONFIG_PROC_FS) += qeth_proc.o obj-$(CONFIG_QETH) += qeth.o diff --git a/drivers/s390/net/cu3088.c b/drivers/s390/net/cu3088.c index 1b0a9f16024c..0075894c71db 100644 --- a/drivers/s390/net/cu3088.c +++ b/drivers/s390/net/cu3088.c @@ -1,5 +1,5 @@ /* - * $Id: cu3088.c,v 1.34 2004/06/15 13:16:27 pavlic Exp $ + * $Id: cu3088.c,v 1.35 2005/03/30 19:28:52 richtera Exp $ * * CTC / LCS ccw_device driver * @@ -39,6 +39,7 @@ const char *cu3088_type[] = { "FICON channel", "P390 LCS card", "OSA LCS card", + "CLAW channel device", "unknown channel type", "unsupported channel type", }; @@ -51,6 +52,7 @@ static struct ccw_device_id cu3088_ids[] = { { CCW_DEVICE(0x3088, 0x1e), .driver_info = channel_type_ficon }, { CCW_DEVICE(0x3088, 0x01), .driver_info = channel_type_p390 }, { CCW_DEVICE(0x3088, 0x60), .driver_info = channel_type_osa2 }, + { CCW_DEVICE(0x3088, 0x61), .driver_info = channel_type_claw }, { /* end of list */ } }; diff --git a/drivers/s390/net/cu3088.h b/drivers/s390/net/cu3088.h index 0ec49a8b3adc..1753661f702a 100644 --- a/drivers/s390/net/cu3088.h +++ b/drivers/s390/net/cu3088.h @@ -23,6 +23,9 @@ enum channel_types { /* Device is a OSA2 card */ channel_type_osa2, + /* Device is a CLAW channel device */ + channel_type_claw, + /* Device is a channel, but we don't know * anything about it */ channel_type_unknown, -- cgit v1.2.2 From 109a260b66bfbab7ba9f985495791af21f910218 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:19:44 +0200 Subject: [PATCH] s390: multicast address registration in lcs [patch 2/10] s390: multicast address registration in lcs. From: Michael Holzheu When setting lcs devices online you can run into an endless loop, because the code that registers the multicast addresses uses list_for_each_entry instead of list_for_each_entry_safe. Signed-off-by: Frank Pavlic --- drivers/s390/net/lcs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0f76e945b984..8d0262e4adc0 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -11,7 +11,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Martin Schwidefsky * - * $Revision: 1.96 $ $Date: 2004/11/11 13:42:33 $ + * $Revision: 1.97 $ $Date: 2005/03/31 09:42:02 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,7 +59,7 @@ /** * initialization string for output */ -#define VERSION_LCS_C "$Revision: 1.96 $" +#define VERSION_LCS_C "$Revision: 1.97 $" static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; static char debug_buffer[255]; @@ -1160,7 +1160,7 @@ list_modified: } } /* re-insert all entries from the failed_list into ipm_list */ - list_for_each_entry(ipm, &failed_list, list) { + list_for_each_entry_safe(ipm, tmp, &failed_list, list) { list_del_init(&ipm->list); list_add_tail(&ipm->list, &card->ipm_list); } -- cgit v1.2.2 From b5f9d55b64a5c7193f8965c90ba62244ea3180b2 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:35:57 +0200 Subject: [PATCH] s390: set online race in the lcs driver [patch 3/10] s390: set online race in the lcs driver. From: Michael Holzheu There is a race between lcs_stopcard() and lcs_open_device() which can lead to the error 'lcs: Error in starting channel, rc=-16'. lcs_open_device() is invoked when 'ifconfig up' is called due to a hotplug event, which is caused by register_netdev(). In parallel lcs_stopcard() is executed. Both functions are sending lcs commands. The second invocation fails with -EBUSY (-16) as return value. Move invocation of register_netdev() after invocation of lcs_stopcard to avoid the race. Signed-off-by: Frank Pavlic --- drivers/s390/net/lcs.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 8d0262e4adc0..cccfed248e70 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -11,7 +11,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Martin Schwidefsky * - * $Revision: 1.97 $ $Date: 2005/03/31 09:42:02 $ + * $Revision: 1.98 $ $Date: 2005/04/18 13:41:29 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -59,7 +59,7 @@ /** * initialization string for output */ -#define VERSION_LCS_C "$Revision: 1.97 $" +#define VERSION_LCS_C "$Revision: 1.98 $" static char version[] __initdata = "LCS driver ("VERSION_LCS_C "/" VERSION_LCS_H ")"; static char debug_buffer[255]; @@ -1098,14 +1098,6 @@ lcs_check_multicast_support(struct lcs_card *card) PRINT_ERR("Query IPAssist failed. Assuming unsupported!\n"); return -EOPNOTSUPP; } - /* Print out supported assists: IPv6 */ - PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name, - (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ? - "with" : "without"); - /* Print out supported assist: Multicast */ - PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name, - (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ? - "with" : "without"); if (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) return 0; return -EOPNOTSUPP; @@ -2198,30 +2190,39 @@ lcs_new_device(struct ccwgroup_device *ccwgdev) if (!dev) goto out; card->dev = dev; -netdev_out: card->dev->priv = card; card->dev->open = lcs_open_device; card->dev->stop = lcs_stop_device; card->dev->hard_start_xmit = lcs_start_xmit; card->dev->get_stats = lcs_getstats; SET_MODULE_OWNER(dev); - if (lcs_register_netdev(ccwgdev) != 0) - goto out; memcpy(card->dev->dev_addr, card->mac, LCS_MAC_LENGTH); #ifdef CONFIG_IP_MULTICAST if (!lcs_check_multicast_support(card)) card->dev->set_multicast_list = lcs_set_multicast_list; #endif - netif_stop_queue(card->dev); +netdev_out: lcs_set_allowed_threads(card,0xffffffff); if (recover_state == DEV_STATE_RECOVER) { lcs_set_multicast_list(card->dev); card->dev->flags |= IFF_UP; netif_wake_queue(card->dev); card->state = DEV_STATE_UP; - } else + } else { lcs_stopcard(card); + } + if (lcs_register_netdev(ccwgdev) != 0) + goto out; + + /* Print out supported assists: IPv6 */ + PRINT_INFO("LCS device %s %s IPv6 support\n", card->dev->name, + (card->ip_assists_supported & LCS_IPASS_IPV6_SUPPORT) ? + "with" : "without"); + /* Print out supported assist: Multicast */ + PRINT_INFO("LCS device %s %s Multicast support\n", card->dev->name, + (card->ip_assists_supported & LCS_IPASS_MULTICAST_SUPPORT) ? + "with" : "without"); return 0; out: -- cgit v1.2.2 From 7f81947b46c3efacc084ac5033f3fed702e46532 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:36:22 +0200 Subject: [PATCH] s390: schedule_timeout cleanup in ctctty [patch 4/10] s390: schedule_timeout cleanup in ctctty. From: Domen Puncer Use msleep_interruptible() instead of schedule_timeout() to guarantee the task delays as expected. Signed-off-by: Nishanth Aravamudan Signed-off-by: Maximilian Attems Signed-off-by: Domen Puncer Signed-off-by: Frank Pavlic Acked-by: Martin Schwidefsky --- drivers/s390/net/ctctty.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/ctctty.c b/drivers/s390/net/ctctty.c index 9257d60c7833..3080393e823d 100644 --- a/drivers/s390/net/ctctty.c +++ b/drivers/s390/net/ctctty.c @@ -1,5 +1,5 @@ /* - * $Id: ctctty.c,v 1.26 2004/08/04 11:06:55 mschwide Exp $ + * $Id: ctctty.c,v 1.29 2005/04/05 08:50:44 mschwide Exp $ * * CTC / ESCON network driver, tty interface. * @@ -1056,8 +1056,7 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp) info->tty = 0; tty->closing = 0; if (info->blocked_open) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/2); + msleep_interruptible(500); wake_up_interruptible(&info->open_wait); } info->flags &= ~(CTC_ASYNC_NORMAL_ACTIVE | CTC_ASYNC_CLOSING); -- cgit v1.2.2 From 7394c928c849fe2ea5c20b6d73cbe7f220810d94 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:36:47 +0200 Subject: [PATCH] s390: ctc code cleanup [patch 5/10] s390: ctc code cleanup. From: Peter Tiedemann ctc network driver changes: - Some code cleanup. Signed-off-by: Martin Schwidefsky --- drivers/s390/net/ctcdbug.h | 12 +- drivers/s390/net/ctcmain.c | 616 +++++++++++++++------------------------------ drivers/s390/net/ctcmain.h | 276 ++++++++++++++++++++ 3 files changed, 490 insertions(+), 414 deletions(-) create mode 100644 drivers/s390/net/ctcmain.h (limited to 'drivers') diff --git a/drivers/s390/net/ctcdbug.h b/drivers/s390/net/ctcdbug.h index ef8883951720..7fe2ebd1792d 100644 --- a/drivers/s390/net/ctcdbug.h +++ b/drivers/s390/net/ctcdbug.h @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.4 $) + * linux/drivers/s390/net/ctcdbug.h ($Revision: 1.5 $) * * CTC / ESCON network driver - s390 dbf exploit. * @@ -9,7 +9,7 @@ * Author(s): Original Code written by * Peter Tiedemann (ptiedem@de.ibm.com) * - * $Revision: 1.4 $ $Date: 2004/10/15 09:26:58 $ + * $Revision: 1.5 $ $Date: 2005/02/27 19:46:44 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,9 +25,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - +#ifndef _CTCDBUG_H_ +#define _CTCDBUG_H_ #include +#include "ctcmain.h" /** * Debug Facility stuff */ @@ -41,7 +43,7 @@ #define CTC_DBF_DATA_LEN 128 #define CTC_DBF_DATA_INDEX 3 #define CTC_DBF_DATA_NR_AREAS 1 -#define CTC_DBF_DATA_LEVEL 2 +#define CTC_DBF_DATA_LEVEL 3 #define CTC_DBF_TRACE_NAME "ctc_trace" #define CTC_DBF_TRACE_LEN 16 @@ -121,3 +123,5 @@ hex_dump(unsigned char *buf, size_t len) printk("\n"); } + +#endif diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c index 7266bf5ea659..ff3e95e07e89 100644 --- a/drivers/s390/net/ctcmain.c +++ b/drivers/s390/net/ctcmain.c @@ -1,5 +1,5 @@ /* - * $Id: ctcmain.c,v 1.72 2005/03/17 10:51:52 ptiedem Exp $ + * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $ * * CTC / ESCON network driver * @@ -37,12 +37,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.72 $ + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $ * */ #undef DEBUG - #include #include #include @@ -74,288 +73,13 @@ #include "ctctty.h" #include "fsm.h" #include "cu3088.h" + #include "ctcdbug.h" +#include "ctcmain.h" MODULE_AUTHOR("(C) 2000 IBM Corp. by Fritz Elfert (felfert@millenux.com)"); MODULE_DESCRIPTION("Linux for S/390 CTC/Escon Driver"); MODULE_LICENSE("GPL"); - -/** - * CCW commands, used in this driver. - */ -#define CCW_CMD_WRITE 0x01 -#define CCW_CMD_READ 0x02 -#define CCW_CMD_SET_EXTENDED 0xc3 -#define CCW_CMD_PREPARE 0xe3 - -#define CTC_PROTO_S390 0 -#define CTC_PROTO_LINUX 1 -#define CTC_PROTO_LINUX_TTY 2 -#define CTC_PROTO_OS390 3 -#define CTC_PROTO_MAX 3 - -#define CTC_BUFSIZE_LIMIT 65535 -#define CTC_BUFSIZE_DEFAULT 32768 - -#define CTC_TIMEOUT_5SEC 5000 - -#define CTC_INITIAL_BLOCKLEN 2 - -#define READ 0 -#define WRITE 1 - -#define CTC_ID_SIZE BUS_ID_SIZE+3 - - -struct ctc_profile { - unsigned long maxmulti; - unsigned long maxcqueue; - unsigned long doios_single; - unsigned long doios_multi; - unsigned long txlen; - unsigned long tx_time; - struct timespec send_stamp; -}; - -/** - * Definition of one channel - */ -struct channel { - - /** - * Pointer to next channel in list. - */ - struct channel *next; - char id[CTC_ID_SIZE]; - struct ccw_device *cdev; - - /** - * Type of this channel. - * CTC/A or Escon for valid channels. - */ - enum channel_types type; - - /** - * Misc. flags. See CHANNEL_FLAGS_... below - */ - __u32 flags; - - /** - * The protocol of this channel - */ - __u16 protocol; - - /** - * I/O and irq related stuff - */ - struct ccw1 *ccw; - struct irb *irb; - - /** - * RX/TX buffer size - */ - int max_bufsize; - - /** - * Transmit/Receive buffer. - */ - struct sk_buff *trans_skb; - - /** - * Universal I/O queue. - */ - struct sk_buff_head io_queue; - - /** - * TX queue for collecting skb's during busy. - */ - struct sk_buff_head collect_queue; - - /** - * Amount of data in collect_queue. - */ - int collect_len; - - /** - * spinlock for collect_queue and collect_len - */ - spinlock_t collect_lock; - - /** - * Timer for detecting unresposive - * I/O operations. - */ - fsm_timer timer; - - /** - * Retry counter for misc. operations. - */ - int retry; - - /** - * The finite state machine of this channel - */ - fsm_instance *fsm; - - /** - * The corresponding net_device this channel - * belongs to. - */ - struct net_device *netdev; - - struct ctc_profile prof; - - unsigned char *trans_skb_data; - - __u16 logflags; -}; - -#define CHANNEL_FLAGS_READ 0 -#define CHANNEL_FLAGS_WRITE 1 -#define CHANNEL_FLAGS_INUSE 2 -#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4 -#define CHANNEL_FLAGS_FAILED 8 -#define CHANNEL_FLAGS_WAITIRQ 16 -#define CHANNEL_FLAGS_RWMASK 1 -#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK) - -#define LOG_FLAG_ILLEGALPKT 1 -#define LOG_FLAG_ILLEGALSIZE 2 -#define LOG_FLAG_OVERRUN 4 -#define LOG_FLAG_NOMEM 8 - -#define CTC_LOGLEVEL_INFO 1 -#define CTC_LOGLEVEL_NOTICE 2 -#define CTC_LOGLEVEL_WARN 4 -#define CTC_LOGLEVEL_EMERG 8 -#define CTC_LOGLEVEL_ERR 16 -#define CTC_LOGLEVEL_DEBUG 32 -#define CTC_LOGLEVEL_CRIT 64 - -#define CTC_LOGLEVEL_DEFAULT \ -(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT) - -#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1) - -static int loglevel = CTC_LOGLEVEL_DEFAULT; - -#define ctc_pr_debug(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0) - -#define ctc_pr_info(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0) - -#define ctc_pr_notice(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0) - -#define ctc_pr_warn(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0) - -#define ctc_pr_emerg(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0) - -#define ctc_pr_err(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0) - -#define ctc_pr_crit(fmt, arg...) \ -do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0) - -/** - * Linked list of all detected channels. - */ -static struct channel *channels = NULL; - -struct ctc_priv { - struct net_device_stats stats; - unsigned long tbusy; - /** - * The finite state machine of this interface. - */ - fsm_instance *fsm; - /** - * The protocol of this device - */ - __u16 protocol; - /** - * Timer for restarting after I/O Errors - */ - fsm_timer restart_timer; - - int buffer_size; - - struct channel *channel[2]; -}; - -/** - * Definition of our link level header. - */ -struct ll_header { - __u16 length; - __u16 type; - __u16 unused; -}; -#define LL_HEADER_LENGTH (sizeof(struct ll_header)) - -/** - * Compatibility macros for busy handling - * of network devices. - */ -static __inline__ void -ctc_clear_busy(struct net_device * dev) -{ - clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy)); - if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) - netif_wake_queue(dev); -} - -static __inline__ int -ctc_test_and_set_busy(struct net_device * dev) -{ - if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) - netif_stop_queue(dev); - return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy); -} - -/** - * Print Banner. - */ -static void -print_banner(void) -{ - static int printed = 0; - char vbuf[] = "$Revision: 1.72 $"; - char *version = vbuf; - - if (printed) - return; - if ((version = strchr(version, ':'))) { - char *p = strchr(version + 1, '$'); - if (p) - *p = '\0'; - } else - version = " ??? "; - printk(KERN_INFO "CTC driver Version%s" -#ifdef DEBUG - " (DEBUG-VERSION, " __DATE__ __TIME__ ")" -#endif - " initialized\n", version); - printed = 1; -} - -/** - * Return type of a detected device. - */ -static enum channel_types -get_channel_type(struct ccw_device_id *id) -{ - enum channel_types type = (enum channel_types) id->driver_info; - - if (type == channel_type_ficon) - type = channel_type_escon; - - return type; -} - /** * States of the interface statemachine. */ @@ -371,7 +95,7 @@ enum dev_states { /** * MUST be always the last element!! */ - NR_DEV_STATES + CTC_NR_DEV_STATES }; static const char *dev_state_names[] = { @@ -399,7 +123,7 @@ enum dev_events { /** * MUST be always the last element!! */ - NR_DEV_EVENTS + CTC_NR_DEV_EVENTS }; static const char *dev_event_names[] = { @@ -476,40 +200,6 @@ enum ch_events { NR_CH_EVENTS, }; -static const char *ch_event_names[] = { - "ccw_device success", - "ccw_device busy", - "ccw_device enodev", - "ccw_device ioerr", - "ccw_device unknown", - - "Status ATTN & BUSY", - "Status ATTN", - "Status BUSY", - - "Unit check remote reset", - "Unit check remote system reset", - "Unit check TX timeout", - "Unit check TX parity", - "Unit check Hardware failure", - "Unit check RX parity", - "Unit check ZERO", - "Unit check Unknown", - - "SubChannel check Unknown", - - "Machine check failure", - "Machine check operational", - - "IRQ normal", - "IRQ final", - - "Timer", - - "Start", - "Stop", -}; - /** * States of the channel statemachine. */ @@ -545,6 +235,87 @@ enum ch_states { NR_CH_STATES, }; +static int loglevel = CTC_LOGLEVEL_DEFAULT; + +/** + * Linked list of all detected channels. + */ +static struct channel *channels = NULL; + +/** + * Print Banner. + */ +static void +print_banner(void) +{ + static int printed = 0; + char vbuf[] = "$Revision: 1.74 $"; + char *version = vbuf; + + if (printed) + return; + if ((version = strchr(version, ':'))) { + char *p = strchr(version + 1, '$'); + if (p) + *p = '\0'; + } else + version = " ??? "; + printk(KERN_INFO "CTC driver Version%s" +#ifdef DEBUG + " (DEBUG-VERSION, " __DATE__ __TIME__ ")" +#endif + " initialized\n", version); + printed = 1; +} + +/** + * Return type of a detected device. + */ +static enum channel_types +get_channel_type(struct ccw_device_id *id) +{ + enum channel_types type = (enum channel_types) id->driver_info; + + if (type == channel_type_ficon) + type = channel_type_escon; + + return type; +} + +static const char *ch_event_names[] = { + "ccw_device success", + "ccw_device busy", + "ccw_device enodev", + "ccw_device ioerr", + "ccw_device unknown", + + "Status ATTN & BUSY", + "Status ATTN", + "Status BUSY", + + "Unit check remote reset", + "Unit check remote system reset", + "Unit check TX timeout", + "Unit check TX parity", + "Unit check Hardware failure", + "Unit check RX parity", + "Unit check ZERO", + "Unit check Unknown", + + "SubChannel check Unknown", + + "Machine check failure", + "Machine check operational", + + "IRQ normal", + "IRQ final", + + "Timer", + + "Start", + "Stop", +}; + static const char *ch_state_names[] = { "Idle", "Stopped", @@ -1934,7 +1705,6 @@ add_channel(struct ccw_device *cdev, enum channel_types type) ch->cdev = cdev; snprintf(ch->id, CTC_ID_SIZE, "ch-%s", cdev->dev.bus_id); ch->type = type; - loglevel = CTC_LOGLEVEL_DEFAULT; ch->fsm = init_fsm(ch->id, ch_state_names, ch_event_names, NR_CH_STATES, NR_CH_EVENTS, ch_fsm, CH_FSM_LEN, GFP_KERNEL); @@ -2697,6 +2467,7 @@ ctc_stats(struct net_device * dev) /* * sysfs attributes */ + static ssize_t buffer_show(struct device *dev, char *buf) { @@ -2715,57 +2486,61 @@ buffer_write(struct device *dev, const char *buf, size_t count) struct ctc_priv *priv; struct net_device *ndev; int bs1; + char buffer[16]; DBF_TEXT(trace, 3, __FUNCTION__); + DBF_TEXT(trace, 3, buf); priv = dev->driver_data; - if (!priv) + if (!priv) { + DBF_TEXT(trace, 3, "bfnopriv"); return -ENODEV; + } + + sscanf(buf, "%u", &bs1); + if (bs1 > CTC_BUFSIZE_LIMIT) + goto einval; + if (bs1 < (576 + LL_HEADER_LENGTH + 2)) + goto einval; + priv->buffer_size = bs1; // just to overwrite the default + ndev = priv->channel[READ]->netdev; - if (!ndev) + if (!ndev) { + DBF_TEXT(trace, 3, "bfnondev"); return -ENODEV; - sscanf(buf, "%u", &bs1); + } - if (bs1 > CTC_BUFSIZE_LIMIT) - return -EINVAL; if ((ndev->flags & IFF_RUNNING) && (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2))) - return -EINVAL; - if (bs1 < (576 + LL_HEADER_LENGTH + 2)) - return -EINVAL; + goto einval; - priv->buffer_size = bs1; - priv->channel[READ]->max_bufsize = - priv->channel[WRITE]->max_bufsize = bs1; + priv->channel[READ]->max_bufsize = bs1; + priv->channel[WRITE]->max_bufsize = bs1; if (!(ndev->flags & IFF_RUNNING)) ndev->mtu = bs1 - LL_HEADER_LENGTH - 2; priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED; + sprintf(buffer, "%d",priv->buffer_size); + DBF_TEXT(trace, 3, buffer); return count; +einval: + DBF_TEXT(trace, 3, "buff_err"); + return -EINVAL; } static ssize_t loglevel_show(struct device *dev, char *buf) { - struct ctc_priv *priv; - - priv = dev->driver_data; - if (!priv) - return -ENODEV; return sprintf(buf, "%d\n", loglevel); } static ssize_t loglevel_write(struct device *dev, const char *buf, size_t count) { - struct ctc_priv *priv; int ll1; DBF_TEXT(trace, 5, __FUNCTION__); - priv = dev->driver_data; - if (!priv) - return -ENODEV; sscanf(buf, "%i", &ll1); if ((ll1 > CTC_LOGLEVEL_MAX) || (ll1 < 0)) @@ -2835,27 +2610,6 @@ stats_write(struct device *dev, const char *buf, size_t count) return count; } -static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); -static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write); -static DEVICE_ATTR(stats, 0644, stats_show, stats_write); - -static int -ctc_add_attributes(struct device *dev) -{ -// device_create_file(dev, &dev_attr_buffer); - device_create_file(dev, &dev_attr_loglevel); - device_create_file(dev, &dev_attr_stats); - return 0; -} - -static void -ctc_remove_attributes(struct device *dev) -{ - device_remove_file(dev, &dev_attr_stats); - device_remove_file(dev, &dev_attr_loglevel); -// device_remove_file(dev, &dev_attr_buffer); -} - static void ctc_netdev_unregister(struct net_device * dev) @@ -2899,52 +2653,6 @@ ctc_free_netdevice(struct net_device * dev, int free_dev) #endif } -/** - * Initialize everything of the net device except the name and the - * channel structs. - */ -static struct net_device * -ctc_init_netdevice(struct net_device * dev, int alloc_device, - struct ctc_priv *privptr) -{ - if (!privptr) - return NULL; - - DBF_TEXT(setup, 3, __FUNCTION__); - if (alloc_device) { - dev = kmalloc(sizeof (struct net_device), GFP_KERNEL); - if (!dev) - return NULL; - memset(dev, 0, sizeof (struct net_device)); - } - - dev->priv = privptr; - privptr->fsm = init_fsm("ctcdev", dev_state_names, - dev_event_names, NR_DEV_STATES, NR_DEV_EVENTS, - dev_fsm, DEV_FSM_LEN, GFP_KERNEL); - if (privptr->fsm == NULL) { - if (alloc_device) - kfree(dev); - return NULL; - } - fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); - fsm_settimer(privptr->fsm, &privptr->restart_timer); - if (dev->mtu == 0) - dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2; - dev->hard_start_xmit = ctc_tx; - dev->open = ctc_open; - dev->stop = ctc_close; - dev->get_stats = ctc_stats; - dev->change_mtu = ctc_change_mtu; - dev->hard_header_len = LL_HEADER_LENGTH + 2; - dev->addr_len = 0; - dev->type = ARPHRD_SLIP; - dev->tx_queue_len = 100; - dev->flags = IFF_POINTOPOINT | IFF_NOARP; - SET_MODULE_OWNER(dev); - return dev; -} - static ssize_t ctc_proto_show(struct device *dev, char *buf) { @@ -2977,7 +2685,6 @@ ctc_proto_store(struct device *dev, const char *buf, size_t count) return count; } -static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store); static ssize_t ctc_type_show(struct device *dev, char *buf) @@ -2991,8 +2698,13 @@ ctc_type_show(struct device *dev, char *buf) return sprintf(buf, "%s\n", cu3088_type[cgdev->cdev[0]->id.driver_info]); } +static DEVICE_ATTR(buffer, 0644, buffer_show, buffer_write); +static DEVICE_ATTR(protocol, 0644, ctc_proto_show, ctc_proto_store); static DEVICE_ATTR(type, 0444, ctc_type_show, NULL); +static DEVICE_ATTR(loglevel, 0644, loglevel_show, loglevel_write); +static DEVICE_ATTR(stats, 0644, stats_show, stats_write); + static struct attribute *ctc_attr[] = { &dev_attr_protocol.attr, &dev_attr_type.attr, @@ -3004,6 +2716,21 @@ static struct attribute_group ctc_attr_group = { .attrs = ctc_attr, }; +static int +ctc_add_attributes(struct device *dev) +{ + device_create_file(dev, &dev_attr_loglevel); + device_create_file(dev, &dev_attr_stats); + return 0; +} + +static void +ctc_remove_attributes(struct device *dev) +{ + device_remove_file(dev, &dev_attr_stats); + device_remove_file(dev, &dev_attr_loglevel); +} + static int ctc_add_files(struct device *dev) { @@ -3028,15 +2755,15 @@ ctc_remove_files(struct device *dev) * * @returns 0 on success, !0 on failure. */ - static int ctc_probe_device(struct ccwgroup_device *cgdev) { struct ctc_priv *priv; int rc; + char buffer[16]; pr_debug("%s() called\n", __FUNCTION__); - DBF_TEXT(trace, 3, __FUNCTION__); + DBF_TEXT(setup, 3, __FUNCTION__); if (!get_device(&cgdev->dev)) return -ENODEV; @@ -3060,9 +2787,69 @@ ctc_probe_device(struct ccwgroup_device *cgdev) cgdev->cdev[1]->handler = ctc_irq_handler; cgdev->dev.driver_data = priv; + sprintf(buffer, "%p", priv); + DBF_TEXT(data, 3, buffer); + + sprintf(buffer, "%u", (unsigned int)sizeof(struct ctc_priv)); + DBF_TEXT(data, 3, buffer); + + sprintf(buffer, "%p", &channels); + DBF_TEXT(data, 3, buffer); + + sprintf(buffer, "%u", (unsigned int)sizeof(struct channel)); + DBF_TEXT(data, 3, buffer); + return 0; } +/** + * Initialize everything of the net device except the name and the + * channel structs. + */ +static struct net_device * +ctc_init_netdevice(struct net_device * dev, int alloc_device, + struct ctc_priv *privptr) +{ + if (!privptr) + return NULL; + + DBF_TEXT(setup, 3, __FUNCTION__); + + if (alloc_device) { + dev = kmalloc(sizeof (struct net_device), GFP_KERNEL); + if (!dev) + return NULL; + memset(dev, 0, sizeof (struct net_device)); + } + + dev->priv = privptr; + privptr->fsm = init_fsm("ctcdev", dev_state_names, + dev_event_names, CTC_NR_DEV_STATES, CTC_NR_DEV_EVENTS, + dev_fsm, DEV_FSM_LEN, GFP_KERNEL); + if (privptr->fsm == NULL) { + if (alloc_device) + kfree(dev); + return NULL; + } + fsm_newstate(privptr->fsm, DEV_STATE_STOPPED); + fsm_settimer(privptr->fsm, &privptr->restart_timer); + if (dev->mtu == 0) + dev->mtu = CTC_BUFSIZE_DEFAULT - LL_HEADER_LENGTH - 2; + dev->hard_start_xmit = ctc_tx; + dev->open = ctc_open; + dev->stop = ctc_close; + dev->get_stats = ctc_stats; + dev->change_mtu = ctc_change_mtu; + dev->hard_header_len = LL_HEADER_LENGTH + 2; + dev->addr_len = 0; + dev->type = ARPHRD_SLIP; + dev->tx_queue_len = 100; + dev->flags = IFF_POINTOPOINT | IFF_NOARP; + SET_MODULE_OWNER(dev); + return dev; +} + + /** * * Setup an interface. @@ -3081,6 +2868,7 @@ ctc_new_device(struct ccwgroup_device *cgdev) struct ctc_priv *privptr; struct net_device *dev; int ret; + char buffer[16]; pr_debug("%s() called\n", __FUNCTION__); DBF_TEXT(setup, 3, __FUNCTION__); @@ -3089,6 +2877,9 @@ ctc_new_device(struct ccwgroup_device *cgdev) if (!privptr) return -ENODEV; + sprintf(buffer, "%d", privptr->buffer_size); + DBF_TEXT(setup, 3, buffer); + type = get_channel_type(&cgdev->cdev[0]->id); snprintf(read_id, CTC_ID_SIZE, "ch-%s", cgdev->cdev[0]->dev.bus_id); @@ -3177,9 +2968,10 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev) struct ctc_priv *priv; struct net_device *ndev; - DBF_TEXT(trace, 3, __FUNCTION__); + DBF_TEXT(setup, 3, __FUNCTION__); pr_debug("%s() called\n", __FUNCTION__); + priv = cgdev->dev.driver_data; ndev = NULL; if (!priv) @@ -3215,7 +3007,6 @@ ctc_shutdown_device(struct ccwgroup_device *cgdev) channel_remove(priv->channel[READ]); if (priv->channel[WRITE]) channel_remove(priv->channel[WRITE]); - priv->channel[READ] = priv->channel[WRITE] = NULL; return 0; @@ -3228,7 +3019,7 @@ ctc_remove_device(struct ccwgroup_device *cgdev) struct ctc_priv *priv; pr_debug("%s() called\n", __FUNCTION__); - DBF_TEXT(trace, 3, __FUNCTION__); + DBF_TEXT(setup, 3, __FUNCTION__); priv = cgdev->dev.driver_data; if (!priv) @@ -3265,6 +3056,7 @@ static struct ccwgroup_driver ctc_group_driver = { static void __exit ctc_exit(void) { + DBF_TEXT(setup, 3, __FUNCTION__); unregister_cu3088_discipline(&ctc_group_driver); ctc_tty_cleanup(); ctc_unregister_dbf_views(); @@ -3282,6 +3074,10 @@ ctc_init(void) { int ret = 0; + loglevel = CTC_LOGLEVEL_DEFAULT; + + DBF_TEXT(setup, 3, __FUNCTION__); + print_banner(); ret = ctc_register_dbf_views(); diff --git a/drivers/s390/net/ctcmain.h b/drivers/s390/net/ctcmain.h new file mode 100644 index 000000000000..ba3605f16335 --- /dev/null +++ b/drivers/s390/net/ctcmain.h @@ -0,0 +1,276 @@ +/* + * $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $ + * + * CTC / ESCON network driver + * + * Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation + * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com) + Peter Tiedemann (ptiedem@de.ibm.com) + * + * + * Documentation used: + * - Principles of Operation (IBM doc#: SA22-7201-06) + * - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02) + * - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535) + * - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00) + * - ESCON I/O Interface (IBM doc#: SA22-7202-029 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $ + * + */ + +#ifndef _CTCMAIN_H_ +#define _CTCMAIN_H_ + +#include +#include + +#include "ctctty.h" +#include "fsm.h" +#include "cu3088.h" + + +/** + * CCW commands, used in this driver. + */ +#define CCW_CMD_WRITE 0x01 +#define CCW_CMD_READ 0x02 +#define CCW_CMD_SET_EXTENDED 0xc3 +#define CCW_CMD_PREPARE 0xe3 + +#define CTC_PROTO_S390 0 +#define CTC_PROTO_LINUX 1 +#define CTC_PROTO_LINUX_TTY 2 +#define CTC_PROTO_OS390 3 +#define CTC_PROTO_MAX 3 + +#define CTC_BUFSIZE_LIMIT 65535 +#define CTC_BUFSIZE_DEFAULT 32768 + +#define CTC_TIMEOUT_5SEC 5000 + +#define CTC_INITIAL_BLOCKLEN 2 + +#define READ 0 +#define WRITE 1 + +#define CTC_ID_SIZE BUS_ID_SIZE+3 + + +struct ctc_profile { + unsigned long maxmulti; + unsigned long maxcqueue; + unsigned long doios_single; + unsigned long doios_multi; + unsigned long txlen; + unsigned long tx_time; + struct timespec send_stamp; +}; + +/** + * Definition of one channel + */ +struct channel { + + /** + * Pointer to next channel in list. + */ + struct channel *next; + char id[CTC_ID_SIZE]; + struct ccw_device *cdev; + + /** + * Type of this channel. + * CTC/A or Escon for valid channels. + */ + enum channel_types type; + + /** + * Misc. flags. See CHANNEL_FLAGS_... below + */ + __u32 flags; + + /** + * The protocol of this channel + */ + __u16 protocol; + + /** + * I/O and irq related stuff + */ + struct ccw1 *ccw; + struct irb *irb; + + /** + * RX/TX buffer size + */ + int max_bufsize; + + /** + * Transmit/Receive buffer. + */ + struct sk_buff *trans_skb; + + /** + * Universal I/O queue. + */ + struct sk_buff_head io_queue; + + /** + * TX queue for collecting skb's during busy. + */ + struct sk_buff_head collect_queue; + + /** + * Amount of data in collect_queue. + */ + int collect_len; + + /** + * spinlock for collect_queue and collect_len + */ + spinlock_t collect_lock; + + /** + * Timer for detecting unresposive + * I/O operations. + */ + fsm_timer timer; + + /** + * Retry counter for misc. operations. + */ + int retry; + + /** + * The finite state machine of this channel + */ + fsm_instance *fsm; + + /** + * The corresponding net_device this channel + * belongs to. + */ + struct net_device *netdev; + + struct ctc_profile prof; + + unsigned char *trans_skb_data; + + __u16 logflags; +}; + +#define CHANNEL_FLAGS_READ 0 +#define CHANNEL_FLAGS_WRITE 1 +#define CHANNEL_FLAGS_INUSE 2 +#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4 +#define CHANNEL_FLAGS_FAILED 8 +#define CHANNEL_FLAGS_WAITIRQ 16 +#define CHANNEL_FLAGS_RWMASK 1 +#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK) + +#define LOG_FLAG_ILLEGALPKT 1 +#define LOG_FLAG_ILLEGALSIZE 2 +#define LOG_FLAG_OVERRUN 4 +#define LOG_FLAG_NOMEM 8 + +#define CTC_LOGLEVEL_INFO 1 +#define CTC_LOGLEVEL_NOTICE 2 +#define CTC_LOGLEVEL_WARN 4 +#define CTC_LOGLEVEL_EMERG 8 +#define CTC_LOGLEVEL_ERR 16 +#define CTC_LOGLEVEL_DEBUG 32 +#define CTC_LOGLEVEL_CRIT 64 + +#define CTC_LOGLEVEL_DEFAULT \ +(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT) + +#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1) + +#define ctc_pr_debug(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0) + +#define ctc_pr_info(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0) + +#define ctc_pr_notice(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0) + +#define ctc_pr_warn(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0) + +#define ctc_pr_emerg(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0) + +#define ctc_pr_err(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0) + +#define ctc_pr_crit(fmt, arg...) \ +do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0) + +struct ctc_priv { + struct net_device_stats stats; + unsigned long tbusy; + /** + * The finite state machine of this interface. + */ + fsm_instance *fsm; + /** + * The protocol of this device + */ + __u16 protocol; + /** + * Timer for restarting after I/O Errors + */ + fsm_timer restart_timer; + + int buffer_size; + + struct channel *channel[2]; +}; + +/** + * Definition of our link level header. + */ +struct ll_header { + __u16 length; + __u16 type; + __u16 unused; +}; +#define LL_HEADER_LENGTH (sizeof(struct ll_header)) + +/** + * Compatibility macros for busy handling + * of network devices. + */ +static __inline__ void +ctc_clear_busy(struct net_device * dev) +{ + clear_bit(0, &(((struct ctc_priv *) dev->priv)->tbusy)); + if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_wake_queue(dev); +} + +static __inline__ int +ctc_test_and_set_busy(struct net_device * dev) +{ + if (((struct ctc_priv *)dev->priv)->protocol != CTC_PROTO_LINUX_TTY) + netif_stop_queue(dev); + return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy); +} + +#endif -- cgit v1.2.2 From 5e39f2933f6707fc824b5e419dcac8ced67a57b6 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:37:00 +0200 Subject: [PATCH] s390: enable iucv_send2way_xxx functions [patch 6/10] s390: enable iucv_send2way_xxx functions. From: Ursula Braun-Krahl The SSL-Server of z/VM wants to use the iucv_send2way and iucv_send2way_array function. Enable them again. Signed-off-by: Frank Pavlic --- drivers/s390/net/iucv.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/iucv.c b/drivers/s390/net/iucv.c index 1ac6563ee3e0..e08e74e16124 100644 --- a/drivers/s390/net/iucv.c +++ b/drivers/s390/net/iucv.c @@ -1,5 +1,5 @@ /* - * $Id: iucv.c,v 1.43 2005/02/09 14:47:43 braunu Exp $ + * $Id: iucv.c,v 1.45 2005/04/26 22:59:06 braunu Exp $ * * IUCV network driver * @@ -29,7 +29,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.43 $ + * RELEASE-TAG: IUCV lowlevel driver $Revision: 1.45 $ * */ @@ -355,7 +355,7 @@ do { \ static void iucv_banner(void) { - char vbuf[] = "$Revision: 1.43 $"; + char vbuf[] = "$Revision: 1.45 $"; char *version = vbuf; if ((version = strchr(version, ':'))) { @@ -2553,12 +2553,12 @@ EXPORT_SYMBOL (iucv_resume); #endif EXPORT_SYMBOL (iucv_reply_prmmsg); EXPORT_SYMBOL (iucv_send); -#if 0 EXPORT_SYMBOL (iucv_send2way); EXPORT_SYMBOL (iucv_send2way_array); -EXPORT_SYMBOL (iucv_send_array); EXPORT_SYMBOL (iucv_send2way_prmmsg); EXPORT_SYMBOL (iucv_send2way_prmmsg_array); +#if 0 +EXPORT_SYMBOL (iucv_send_array); EXPORT_SYMBOL (iucv_send_prmmsg); EXPORT_SYMBOL (iucv_setmask); #endif -- cgit v1.2.2 From d801145d910cc4a0fb418dda1dee227cec993cbd Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:37:53 +0200 Subject: [PATCH] s390: qeth bug fixes [patch 7/10] s390: qeth bug fixes. From: Frank Pavlic qeth network driver changes: - Removed redundant code, use the same qeth_fill_buffer_frag for TSO path either - Using skb->frags solely is not correct since skb->data still points to the beginning of the whole data, even when it is a small portion we have to fill the qdio buffer with it. Signed-off-by: Frank Pavlic --- drivers/s390/net/qeth.h | 13 +++++++- drivers/s390/net/qeth_eddp.c | 15 ++-------- drivers/s390/net/qeth_main.c | 49 +++--------------------------- drivers/s390/net/qeth_tso.c | 49 +++++++----------------------- drivers/s390/net/qeth_tso.h | 71 ++++++++++++++++++++++++++++++++++++-------- 5 files changed, 86 insertions(+), 111 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index a341041a6cf7..501b87e6875a 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -24,7 +24,7 @@ #include "qeth_mpc.h" -#define VERSION_QETH_H "$Revision: 1.135 $" +#define VERSION_QETH_H "$Revision: 1.136 $" #ifdef CONFIG_QETH_IPV6 #define QETH_VERSION_IPV6 ":IPv6" @@ -866,6 +866,17 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size) return hdr; } +static inline int +qeth_get_skb_data_len(struct sk_buff *skb) +{ + int len = skb->len; + int i; + + for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) + len -= skb_shinfo(skb)->frags[i].size; + return len; +} + inline static int qeth_get_hlen(__u8 link_type) { diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 7ee1c06ed68a..45aa4a962daf 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.11 $) + * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.12 $) * * Enhanced Device Driver Packing (EDDP) support for the qeth driver. * @@ -8,7 +8,7 @@ * * Author(s): Thomas Spatzier * - * $Revision: 1.11 $ $Date: 2005/03/24 09:04:18 $ + * $Revision: 1.12 $ $Date: 2005/04/01 21:40:40 $ * */ #include @@ -202,17 +202,6 @@ out: return flush_cnt; } -static inline int -qeth_get_skb_data_len(struct sk_buff *skb) -{ - int len = skb->len; - int i; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) - len -= skb_shinfo(skb)->frags[i].size; - return len; -} - static inline void qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx, struct qeth_eddp_data *eddp) diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 607b92542df6..17e8d16fa06c 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.206 $) + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.207 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -12,7 +12,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Thomas Spatzier * - * $Revision: 1.206 $ $Date: 2005/03/24 09:04:18 $ + * $Revision: 1.207 $ $Date: 2005/04/01 21:40:40 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,7 +80,7 @@ qeth_eyecatcher(void) #include "qeth_eddp.h" #include "qeth_tso.h" -#define VERSION_QETH_C "$Revision: 1.206 $" +#define VERSION_QETH_C "$Revision: 1.207 $" static const char *version = "qeth S/390 OSA-Express driver"; /** @@ -3893,47 +3893,6 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, } } -static inline void -__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer, - int *next_element_to_fill) -{ - int length = skb->len; - struct skb_frag_struct *frag; - int fragno; - unsigned long addr; - int element; - int first_lap = 1; - - fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */ - element = *next_element_to_fill + fragno; - while (length > 0) { - if (fragno > 0) { - frag = &skb_shinfo(skb)->frags[fragno - 1]; - addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + - frag->page_offset; - buffer->element[element].addr = (char *)addr; - buffer->element[element].length = frag->size; - length -= frag->size; - if (first_lap) - buffer->element[element].flags = - SBAL_FLAGS_LAST_FRAG; - else - buffer->element[element].flags = - SBAL_FLAGS_MIDDLE_FRAG; - } else { - buffer->element[element].addr = skb->data; - buffer->element[element].length = length; - length = 0; - buffer->element[element].flags = - SBAL_FLAGS_FIRST_FRAG; - } - element--; - fragno--; - first_lap = 0; - } - *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1; -} - static inline void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, int *next_element_to_fill) @@ -3991,7 +3950,7 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue, __qeth_fill_buffer(skb, buffer, (int *)&buf->next_element_to_fill); else - __qeth_fill_buffer_frag(skb, buffer, + __qeth_fill_buffer_frag(skb, buffer, 0, (int *)&buf->next_element_to_fill); if (!queue->do_pack) { diff --git a/drivers/s390/net/qeth_tso.c b/drivers/s390/net/qeth_tso.c index c91976274e7b..4e58f19cb71c 100644 --- a/drivers/s390/net/qeth_tso.c +++ b/drivers/s390/net/qeth_tso.c @@ -1,5 +1,5 @@ /* - * linux/drivers/s390/net/qeth_tso.c ($Revision: 1.6 $) + * linux/drivers/s390/net/qeth_tso.c ($Revision: 1.7 $) * * Header file for qeth TCP Segmentation Offload support. * @@ -7,7 +7,7 @@ * * Author(s): Frank Pavlic * - * $Revision: 1.6 $ $Date: 2005/03/24 09:04:18 $ + * $Revision: 1.7 $ $Date: 2005/04/01 21:40:41 $ * */ @@ -144,38 +144,6 @@ qeth_tso_get_queue_buffer(struct qeth_qdio_out_q *queue) return flush_cnt; } -static inline void -__qeth_tso_fill_buffer_frag(struct qeth_qdio_out_buffer *buf, - struct sk_buff *skb) -{ - struct skb_frag_struct *frag; - struct qdio_buffer *buffer; - int fragno, cnt, element; - unsigned long addr; - - QETH_DBF_TEXT(trace, 6, "tsfilfrg"); - - /*initialize variables ...*/ - fragno = skb_shinfo(skb)->nr_frags; - buffer = buf->buffer; - element = buf->next_element_to_fill; - /*fill buffer elements .....*/ - for (cnt = 0; cnt < fragno; cnt++) { - frag = &skb_shinfo(skb)->frags[cnt]; - addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + - frag->page_offset; - buffer->element[element].addr = (char *)addr; - buffer->element[element].length = frag->size; - if (cnt < (fragno - 1)) - buffer->element[element].flags = - SBAL_FLAGS_MIDDLE_FRAG; - else - buffer->element[element].flags = - SBAL_FLAGS_LAST_FRAG; - element++; - } - buf->next_element_to_fill = element; -} static inline int qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf, @@ -205,19 +173,22 @@ qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf, buffer->element[element].length = hdr_len; buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG; buf->next_element_to_fill++; - + /*check if we have frags ...*/ if (skb_shinfo(skb)->nr_frags > 0) { - __qeth_tso_fill_buffer_frag(buf, skb); + skb->len = length; + skb->data = data; + __qeth_fill_buffer_frag(skb, buffer,1, + (int *)&buf->next_element_to_fill); goto out; } - /*start filling buffer entries ...*/ + /*... if not, use this */ element++; while (length > 0) { /* length_here is the remaining amount of data in this page */ length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); if (length < length_here) - length_here = length; + length_here = length; buffer->element[element].addr = data; buffer->element[element].length = length_here; length -= length_here; @@ -230,9 +201,9 @@ qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf, data += length_here; element++; } - /*set the buffer to primed ...*/ buf->next_element_to_fill = element; out: + /*prime buffer now ...*/ atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED); return 1; } diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index 83504dee3f57..ff585ae49b6c 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h @@ -1,5 +1,5 @@ /* - * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.4 $) + * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.5 $) * * Header file for qeth TCP Segmentation Offload support. * @@ -7,7 +7,7 @@ * * Author(s): Frank Pavlic * - * $Revision: 1.4 $ $Date: 2005/03/24 09:04:18 $ + * $Revision: 1.5 $ $Date: 2005/04/01 21:40:41 $ * */ #ifndef __QETH_TSO_H__ @@ -37,22 +37,67 @@ struct qeth_hdr_tso { } __attribute__ ((packed)); /*some helper functions*/ - static inline int qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) { int elements_needed = 0; - if (skb_shinfo(skb)->nr_frags > 0) - elements_needed = (skb_shinfo(skb)->nr_frags + 1); - if (elements_needed == 0 ) - elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) - + skb->len) >> PAGE_SHIFT); - if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ - PRINT_ERR("qeth_do_send_packet: invalid size of " - "IP packet. Discarded."); - return 0; + if (skb_shinfo(skb)->nr_frags > 0) + elements_needed = (skb_shinfo(skb)->nr_frags + 1); + if (elements_needed == 0 ) + elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) + + skb->len) >> PAGE_SHIFT); + if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ + PRINT_ERR("qeth_do_send_packet: invalid size of " + "IP packet. Discarded."); + return 0; + } + return elements_needed; +} + +static inline void +__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer, + int is_tso, int *next_element_to_fill) +{ + int length = skb->len; + struct skb_frag_struct *frag; + int fragno; + unsigned long addr; + int element; + int first_lap = 1; + + fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */ + element = *next_element_to_fill + fragno; + while (length > 0) { + if (fragno > 0) { + frag = &skb_shinfo(skb)->frags[fragno - 1]; + addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + + frag->page_offset; + buffer->element[element].addr = (char *)addr; + buffer->element[element].length = frag->size; + length -= frag->size; + if (first_lap) + buffer->element[element].flags = + SBAL_FLAGS_LAST_FRAG; + else + buffer->element[element].flags = + SBAL_FLAGS_MIDDLE_FRAG; + } else { + buffer->element[element].addr = skb->data; + buffer->element[element].length = length; + length = 0; + if (is_tso) + buffer->element[element].flags = + SBAL_FLAGS_MIDDLE_FRAG; + else + buffer->element[element].flags = + SBAL_FLAGS_FIRST_FRAG; + } + element--; + fragno--; + first_lap = 0; } - return elements_needed; + *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1; } + #endif /* __QETH_TSO_H__ */ -- cgit v1.2.2 From e23dd9cdd676323c95fab47dc55123ba18f7e1ff Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:38:11 +0200 Subject: [PATCH] s390: fakell for high speed token ring [patch 8/10] s390: fakell for high speed token ring. From: Michael Holzheu Implement fake-link-layer for high speed token ring. Without it token ring packages get leading ethernet headers, which confuses dhcp. Signed-off-by: Frank Pavlic --- drivers/s390/net/qeth.h | 5 +- drivers/s390/net/qeth_main.c | 136 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 114 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 501b87e6875a..d13c105f74e6 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -24,7 +24,7 @@ #include "qeth_mpc.h" -#define VERSION_QETH_H "$Revision: 1.136 $" +#define VERSION_QETH_H "$Revision: 1.137 $" #ifdef CONFIG_QETH_IPV6 #define QETH_VERSION_IPV6 ":IPv6" @@ -288,7 +288,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) #define QETH_TX_TIMEOUT 100 * HZ #define QETH_HEADER_SIZE 32 #define MAX_PORTNO 15 -#define QETH_FAKE_LL_LEN ETH_HLEN +#define QETH_FAKE_LL_LEN_ETH ETH_HLEN +#define QETH_FAKE_LL_LEN_TR (sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc)) #define QETH_FAKE_LL_V6_ADDR_POS 24 /*IPv6 address autoconfiguration stuff*/ diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 17e8d16fa06c..2afe515f928d 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.207 $) + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.209 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -12,7 +12,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Thomas Spatzier * - * $Revision: 1.207 $ $Date: 2005/04/01 21:40:40 $ + * $Revision: 1.209 $ $Date: 2005/04/18 11:58:48 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,7 +80,7 @@ qeth_eyecatcher(void) #include "qeth_eddp.h" #include "qeth_tso.h" -#define VERSION_QETH_C "$Revision: 1.207 $" +#define VERSION_QETH_C "$Revision: 1.209 $" static const char *version = "qeth S/390 OSA-Express driver"; /** @@ -2152,9 +2152,15 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer, if (!skb_len) return NULL; if (card->options.fake_ll){ - if (!(skb = qeth_get_skb(skb_len + QETH_FAKE_LL_LEN))) - goto no_mem; - skb_pull(skb, QETH_FAKE_LL_LEN); + if(card->dev->type == ARPHRD_IEEE802_TR){ + if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR))) + goto no_mem; + skb_reserve(skb,QETH_FAKE_LL_LEN_TR); + } else { + if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH))) + goto no_mem; + skb_reserve(skb,QETH_FAKE_LL_LEN_ETH); + } } else if (!(skb = qeth_get_skb(skb_len))) goto no_mem; data_ptr = element->addr + offset; @@ -2229,14 +2235,68 @@ qeth_type_trans(struct sk_buff *skb, struct net_device *dev) } static inline void -qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, +qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb, + struct qeth_hdr *hdr) +{ + struct trh_hdr *fake_hdr; + struct trllc *fake_llc; + struct iphdr *ip_hdr; + + QETH_DBF_TEXT(trace,5,"skbfktr"); + skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_TR; + /* this is a fake ethernet header */ + fake_hdr = (struct trh_hdr *) skb->mac.raw; + + /* the destination MAC address */ + switch (skb->pkt_type){ + case PACKET_MULTICAST: + switch (skb->protocol){ +#ifdef CONFIG_QETH_IPV6 + case __constant_htons(ETH_P_IPV6): + ndisc_mc_map((struct in6_addr *) + skb->data + QETH_FAKE_LL_V6_ADDR_POS, + fake_hdr->daddr, card->dev, 0); + break; +#endif /* CONFIG_QETH_IPV6 */ + case __constant_htons(ETH_P_IP): + ip_hdr = (struct iphdr *)skb->data; + ip_tr_mc_map(ip_hdr->daddr, fake_hdr->daddr); + break; + default: + memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN); + } + break; + case PACKET_BROADCAST: + memset(fake_hdr->daddr, 0xff, TR_ALEN); + break; + default: + memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN); + } + /* the source MAC address */ + if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR) + memcpy(fake_hdr->saddr, &hdr->hdr.l3.dest_addr[2], TR_ALEN); + else + memset(fake_hdr->saddr, 0, TR_ALEN); + fake_hdr->rcf=0; + fake_llc = (struct trllc*)&(fake_hdr->rcf); + fake_llc->dsap = EXTENDED_SAP; + fake_llc->ssap = EXTENDED_SAP; + fake_llc->llc = UI_CMD; + fake_llc->protid[0] = 0; + fake_llc->protid[1] = 0; + fake_llc->protid[2] = 0; + fake_llc->ethertype = ETH_P_IP; +} + +static inline void +qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *hdr) { struct ethhdr *fake_hdr; struct iphdr *ip_hdr; - QETH_DBF_TEXT(trace,5,"skbfake"); - skb->mac.raw = skb->data - QETH_FAKE_LL_LEN; + QETH_DBF_TEXT(trace,5,"skbfketh"); + skb->mac.raw = skb->data - QETH_FAKE_LL_LEN_ETH; /* this is a fake ethernet header */ fake_hdr = (struct ethhdr *) skb->mac.raw; @@ -2253,10 +2313,7 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, #endif /* CONFIG_QETH_IPV6 */ case __constant_htons(ETH_P_IP): ip_hdr = (struct iphdr *)skb->data; - if (card->dev->type == ARPHRD_IEEE802_TR) - ip_tr_mc_map(ip_hdr->daddr, fake_hdr->h_dest); - else - ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest); + ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest); break; default: memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN); @@ -2277,6 +2334,16 @@ qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, fake_hdr->h_proto = skb->protocol; } +static inline void +qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb, + struct qeth_hdr *hdr) +{ + if (card->dev->type == ARPHRD_IEEE802_TR) + qeth_rebuild_skb_fake_ll_tr(card, skb, hdr); + else + qeth_rebuild_skb_fake_ll_eth(card, skb, hdr); +} + static inline void qeth_rebuild_skb_vlan(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *hdr) @@ -3440,16 +3507,25 @@ qeth_fake_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len) { - struct ethhdr *hdr; + if(dev->type == ARPHRD_IEEE802_TR){ + struct trh_hdr *hdr; + hdr = (struct trh_hdr *)skb_push(skb, QETH_FAKE_LL_LEN_TR); + memcpy(hdr->saddr, dev->dev_addr, TR_ALEN); + memcpy(hdr->daddr, "FAKELL", TR_ALEN); + return QETH_FAKE_LL_LEN_TR; + + } else { + struct ethhdr *hdr; + hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN_ETH); + memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN); + memcpy(hdr->h_dest, "FAKELL", ETH_ALEN); + if (type != ETH_P_802_3) + hdr->h_proto = htons(type); + else + hdr->h_proto = htons(len); + return QETH_FAKE_LL_LEN_ETH; - hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN); - memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN); - memcpy(hdr->h_dest, "FAKELL", ETH_ALEN); - if (type != ETH_P_802_3) - hdr->h_proto = htons(type); - else - hdr->h_proto = htons(len); - return QETH_FAKE_LL_LEN; + } } static inline int @@ -3882,9 +3958,15 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, memcpy(hdr->hdr.l3.dest_addr, &skb->nh.ipv6h->daddr, 16); } } else { /* passthrough */ - if (!memcmp(skb->data + sizeof(struct qeth_hdr), + if((skb->dev->type == ARPHRD_IEEE802_TR) && + !memcmp(skb->data + sizeof(struct qeth_hdr) + 2, + skb->dev->broadcast, 6)) { + hdr->hdr.l3.flags = QETH_CAST_BROADCAST | + QETH_HDR_PASSTHRU; + } else if (!memcmp(skb->data + sizeof(struct qeth_hdr), skb->dev->broadcast, 6)) { /* broadcast? */ - hdr->hdr.l3.flags = QETH_CAST_BROADCAST | QETH_HDR_PASSTHRU; + hdr->hdr.l3.flags = QETH_CAST_BROADCAST | + QETH_HDR_PASSTHRU; } else { hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ? QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU : @@ -4164,7 +4246,11 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) dev_kfree_skb_irq(skb); return 0; } - skb_pull(skb, QETH_FAKE_LL_LEN); + if(card->dev->type == ARPHRD_IEEE802_TR){ + skb_pull(skb, QETH_FAKE_LL_LEN_TR); + } else { + skb_pull(skb, QETH_FAKE_LL_LEN_ETH); + } } } cast_type = qeth_get_cast_type(card, skb); -- cgit v1.2.2 From 9a4558193662e933588ee53e0202c103a68c9366 Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:38:28 +0200 Subject: [PATCH] s390: qeth bug fixes [patch 9/10] s390: qeth bug fixes. From: Frank Pavlic qeth network driver changes: - Use sizeof(__u16) instead of '2' in qeth_fill_header. Signed-off-by: Frank Pavlic --- drivers/s390/net/qeth_main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 2afe515f928d..e18bcf9fb588 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.209 $) + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.210 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -12,7 +12,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Thomas Spatzier * - * $Revision: 1.209 $ $Date: 2005/04/18 11:58:48 $ + * $Revision: 1.210 $ $Date: 2005/04/18 17:27:39 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,7 +80,7 @@ qeth_eyecatcher(void) #include "qeth_eddp.h" #include "qeth_tso.h" -#define VERSION_QETH_C "$Revision: 1.209 $" +#define VERSION_QETH_C "$Revision: 1.210 $" static const char *version = "qeth S/390 OSA-Express driver"; /** @@ -3959,10 +3959,10 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, } } else { /* passthrough */ if((skb->dev->type == ARPHRD_IEEE802_TR) && - !memcmp(skb->data + sizeof(struct qeth_hdr) + 2, - skb->dev->broadcast, 6)) { - hdr->hdr.l3.flags = QETH_CAST_BROADCAST | - QETH_HDR_PASSTHRU; + !memcmp(skb->data + sizeof(struct qeth_hdr) + + sizeof(__u16), skb->dev->broadcast, 6)) { + hdr->hdr.l3.flags = QETH_CAST_BROADCAST | + QETH_HDR_PASSTHRU; } else if (!memcmp(skb->data + sizeof(struct qeth_hdr), skb->dev->broadcast, 6)) { /* broadcast? */ hdr->hdr.l3.flags = QETH_CAST_BROADCAST | -- cgit v1.2.2 From 05e08a2a297371564020f76d1bf8b3a931d5e1ed Mon Sep 17 00:00:00 2001 From: Frank Pavlic Date: Thu, 12 May 2005 20:39:09 +0200 Subject: [PATCH] s390: qeth bug fixes [patch 10/10] s390: qeth bug fixes. From: Frank Pavlic qeth network driver related changes: - due to OSA hardware changes in TCP Segmentation Offload support we are able now to pack TSO packets too. This fits perfectly in design of qeth buffer handling and sending data respectively. - remove skb_realloc_headroom from the sending path since hard_header_len value provides enough headroom now. - device recovery behaviour improvement - bug fixed in Enhanced Device Driver Packing functionality Signed-off-by: Frank Pavlic --- drivers/s390/net/Makefile | 2 +- drivers/s390/net/qeth.h | 41 ++++--- drivers/s390/net/qeth_eddp.c | 40 +++---- drivers/s390/net/qeth_main.c | 145 +++++++++++++++++------- drivers/s390/net/qeth_tso.c | 256 ------------------------------------------- drivers/s390/net/qeth_tso.h | 193 ++++++++++++++++++++------------ 6 files changed, 273 insertions(+), 404 deletions(-) delete mode 100644 drivers/s390/net/qeth_tso.c (limited to 'drivers') diff --git a/drivers/s390/net/Makefile b/drivers/s390/net/Makefile index 85b590c5701d..90d4d0ef3dd4 100644 --- a/drivers/s390/net/Makefile +++ b/drivers/s390/net/Makefile @@ -10,6 +10,6 @@ obj-$(CONFIG_SMSGIUCV) += smsgiucv.o obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o obj-$(CONFIG_LCS) += lcs.o cu3088.o obj-$(CONFIG_CLAW) += claw.o cu3088.o -qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth_tso.o +qeth-y := qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth-$(CONFIG_PROC_FS) += qeth_proc.o obj-$(CONFIG_QETH) += qeth.o diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index d13c105f74e6..a755b57db46b 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -24,7 +24,7 @@ #include "qeth_mpc.h" -#define VERSION_QETH_H "$Revision: 1.137 $" +#define VERSION_QETH_H "$Revision: 1.139 $" #ifdef CONFIG_QETH_IPV6 #define QETH_VERSION_IPV6 ":IPv6" @@ -370,6 +370,25 @@ struct qeth_hdr { } hdr; } __attribute__ ((packed)); +/*TCP Segmentation Offload header*/ +struct qeth_hdr_ext_tso { + __u16 hdr_tot_len; + __u8 imb_hdr_no; + __u8 reserved; + __u8 hdr_type; + __u8 hdr_version; + __u16 hdr_len; + __u32 payload_len; + __u16 mss; + __u16 dg_hdr_len; + __u8 padding[16]; +} __attribute__ ((packed)); + +struct qeth_hdr_tso { + struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/ + struct qeth_hdr_ext_tso ext; +} __attribute__ ((packed)); + /* flags for qeth_hdr.flags */ #define QETH_HDR_PASSTHRU 0x10 @@ -867,16 +886,6 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size) return hdr; } -static inline int -qeth_get_skb_data_len(struct sk_buff *skb) -{ - int len = skb->len; - int i; - - for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) - len -= skb_shinfo(skb)->frags[i].size; - return len; -} inline static int qeth_get_hlen(__u8 link_type) @@ -885,19 +894,19 @@ qeth_get_hlen(__u8 link_type) switch (link_type) { case QETH_LINK_TYPE_HSTR: case QETH_LINK_TYPE_LANE_TR: - return sizeof(struct qeth_hdr) + TR_HLEN; + return sizeof(struct qeth_hdr_tso) + TR_HLEN; default: #ifdef CONFIG_QETH_VLAN - return sizeof(struct qeth_hdr) + VLAN_ETH_HLEN; + return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN; #else - return sizeof(struct qeth_hdr) + ETH_HLEN; + return sizeof(struct qeth_hdr_tso) + ETH_HLEN; #endif } #else /* CONFIG_QETH_IPV6 */ #ifdef CONFIG_QETH_VLAN - return sizeof(struct qeth_hdr) + VLAN_HLEN; + return sizeof(struct qeth_hdr_tso) + VLAN_HLEN; #else - return sizeof(struct qeth_hdr); + return sizeof(struct qeth_hdr_tso); #endif #endif /* CONFIG_QETH_IPV6 */ } diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c index 45aa4a962daf..f94f1f25eec6 100644 --- a/drivers/s390/net/qeth_eddp.c +++ b/drivers/s390/net/qeth_eddp.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.12 $) + * linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.13 $) * * Enhanced Device Driver Packing (EDDP) support for the qeth driver. * @@ -8,7 +8,7 @@ * * Author(s): Thomas Spatzier * - * $Revision: 1.12 $ $Date: 2005/04/01 21:40:40 $ + * $Revision: 1.13 $ $Date: 2005/05/04 20:19:18 $ * */ #include @@ -85,7 +85,7 @@ void qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf) { struct qeth_eddp_context_reference *ref; - + QETH_DBF_TEXT(trace, 6, "eddprctx"); while (!list_empty(&buf->ctx_list)){ ref = list_entry(buf->ctx_list.next, @@ -139,7 +139,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, "buffer!\n"); goto out; } - } + } /* check if the whole next skb fits into current buffer */ if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) - buf->next_element_to_fill) @@ -152,7 +152,7 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, * and increment ctx's refcnt */ must_refcnt = 1; continue; - } + } if (must_refcnt){ must_refcnt = 0; if (qeth_eddp_buf_ref_context(buf, ctx)){ @@ -204,27 +204,27 @@ out: static inline void qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx, - struct qeth_eddp_data *eddp) + struct qeth_eddp_data *eddp, int data_len) { u8 *page; int page_remainder; int page_offset; - int hdr_len; + int pkt_len; struct qeth_eddp_element *element; QETH_DBF_TEXT(trace, 5, "eddpcrsh"); page = ctx->pages[ctx->offset >> PAGE_SHIFT]; page_offset = ctx->offset % PAGE_SIZE; element = &ctx->elements[ctx->num_elements]; - hdr_len = eddp->nhl + eddp->thl; + pkt_len = eddp->nhl + eddp->thl + data_len; /* FIXME: layer2 and VLAN !!! */ if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) - hdr_len += ETH_HLEN; + pkt_len += ETH_HLEN; if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) - hdr_len += VLAN_HLEN; - /* does complete header fit in current page ? */ + pkt_len += VLAN_HLEN; + /* does complete packet fit in current page ? */ page_remainder = PAGE_SIZE - page_offset; - if (page_remainder < (sizeof(struct qeth_hdr) + hdr_len)){ + if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){ /* no -> go to start of next page */ ctx->offset += page_remainder; page = ctx->pages[ctx->offset >> PAGE_SHIFT]; @@ -270,7 +270,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len, int left_in_frag; int copy_len; u8 *src; - + QETH_DBF_TEXT(trace, 5, "eddpcdtc"); if (skb_shinfo(eddp->skb)->nr_frags == 0) { memcpy(dst, eddp->skb->data + eddp->skb_offset, len); @@ -281,7 +281,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len, while (len > 0) { if (eddp->frag < 0) { /* we're in skb->data */ - left_in_frag = qeth_get_skb_data_len(eddp->skb) + left_in_frag = (eddp->skb->len - eddp->skb->data_len) - eddp->skb_offset; src = eddp->skb->data + eddp->skb_offset; } else { @@ -413,7 +413,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, struct tcphdr *tcph; int data_len; u32 hcsum; - + QETH_DBF_TEXT(trace, 5, "eddpftcp"); eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl; tcph = eddp->skb->h.th; @@ -453,7 +453,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, else hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len); /* fill the next segment into the context */ - qeth_eddp_create_segment_hdrs(ctx, eddp); + qeth_eddp_create_segment_hdrs(ctx, eddp, data_len); qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum); if (eddp->skb_offset >= eddp->skb->len) break; @@ -463,13 +463,13 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, eddp->th.tcp.h.seq += data_len; } } - + static inline int qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx, struct sk_buff *skb, struct qeth_hdr *qhdr) { struct qeth_eddp_data *eddp = NULL; - + QETH_DBF_TEXT(trace, 5, "eddpficx"); /* create our segmentation headers and copy original headers */ if (skb->protocol == ETH_P_IP) @@ -509,7 +509,7 @@ qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb, int hdr_len) { int skbs_per_page; - + QETH_DBF_TEXT(trace, 5, "eddpcanp"); /* can we put multiple skbs in one page? */ skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->tso_size + hdr_len); @@ -589,7 +589,7 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb, struct qeth_hdr *qhdr) { struct qeth_eddp_context *ctx = NULL; - + QETH_DBF_TEXT(trace, 5, "creddpct"); if (skb->protocol == ETH_P_IP) ctx = qeth_eddp_create_context_generic(card, skb, diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index e18bcf9fb588..208127a5033a 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c @@ -1,6 +1,6 @@ /* * - * linux/drivers/s390/net/qeth_main.c ($Revision: 1.210 $) + * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $) * * Linux on zSeries OSA Express and HiperSockets support * @@ -12,7 +12,7 @@ * Frank Pavlic (pavlic@de.ibm.com) and * Thomas Spatzier * - * $Revision: 1.210 $ $Date: 2005/04/18 17:27:39 $ + * $Revision: 1.214 $ $Date: 2005/05/04 20:19:18 $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -80,7 +80,7 @@ qeth_eyecatcher(void) #include "qeth_eddp.h" #include "qeth_tso.h" -#define VERSION_QETH_C "$Revision: 1.210 $" +#define VERSION_QETH_C "$Revision: 1.214 $" static const char *version = "qeth S/390 OSA-Express driver"; /** @@ -158,6 +158,9 @@ qeth_irq_tasklet(unsigned long); static int qeth_set_online(struct ccwgroup_device *); +static int +__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode); + static struct qeth_ipaddr * qeth_get_addr_buffer(enum qeth_prot_versions); @@ -510,10 +513,10 @@ qeth_irq_tasklet(unsigned long data) wake_up(&card->wait_q); } -static int qeth_stop_card(struct qeth_card *); +static int qeth_stop_card(struct qeth_card *, int); static int -qeth_set_offline(struct ccwgroup_device *cgdev) +__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode) { struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data; int rc = 0; @@ -523,7 +526,7 @@ qeth_set_offline(struct ccwgroup_device *cgdev) QETH_DBF_HEX(setup, 3, &card, sizeof(void *)); recover_flag = card->state; - if (qeth_stop_card(card) == -ERESTARTSYS){ + if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){ PRINT_WARN("Stopping card %s interrupted by user!\n", CARD_BUS_ID(card)); return -ERESTARTSYS; @@ -539,6 +542,12 @@ qeth_set_offline(struct ccwgroup_device *cgdev) return 0; } +static int +qeth_set_offline(struct ccwgroup_device *cgdev) +{ + return __qeth_set_offline(cgdev, 0); +} + static int qeth_wait_for_threads(struct qeth_card *card, unsigned long threads); @@ -953,8 +962,8 @@ qeth_recover(void *ptr) PRINT_WARN("Recovery of device %s started ...\n", CARD_BUS_ID(card)); card->use_hard_stop = 1; - qeth_set_offline(card->gdev); - rc = qeth_set_online(card->gdev); + __qeth_set_offline(card->gdev,1); + rc = __qeth_set_online(card->gdev,1); if (!rc) PRINT_INFO("Device %s successfully recovered!\n", CARD_BUS_ID(card)); @@ -3786,16 +3795,12 @@ static inline int qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb, struct qeth_hdr **hdr, int ipv) { - int rc = 0; #ifdef CONFIG_QETH_VLAN u16 *tag; #endif QETH_DBF_TEXT(trace, 6, "prepskb"); - rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr)); - if (rc) - return rc; #ifdef CONFIG_QETH_VLAN if (card->vlangrp && vlan_tx_tag_present(*skb) && ((ipv == 6) || card->options.layer2) ) { @@ -3977,25 +3982,28 @@ qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, static inline void __qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer, - int *next_element_to_fill) + int is_tso, int *next_element_to_fill) { int length = skb->len; int length_here; int element; char *data; - int first_lap = 1; + int first_lap ; element = *next_element_to_fill; data = skb->data; + first_lap = (is_tso == 0 ? 1 : 0); + while (length > 0) { /* length_here is the remaining amount of data in this page */ length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); if (length < length_here) length_here = length; + buffer->element[element].addr = data; buffer->element[element].length = length_here; length -= length_here; - if (!length){ + if (!length) { if (first_lap) buffer->element[element].flags = 0; else @@ -4022,17 +4030,35 @@ qeth_fill_buffer(struct qeth_qdio_out_q *queue, struct sk_buff *skb) { struct qdio_buffer *buffer; - int flush_cnt = 0; + struct qeth_hdr_tso *hdr; + int flush_cnt = 0, hdr_len, large_send = 0; QETH_DBF_TEXT(trace, 6, "qdfillbf"); + buffer = buf->buffer; atomic_inc(&skb->users); skb_queue_tail(&buf->skb_list, skb); + + hdr = (struct qeth_hdr_tso *) skb->data; + /*check first on TSO ....*/ + if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) { + int element = buf->next_element_to_fill; + + hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len; + /*fill first buffer entry only with header information */ + buffer->element[element].addr = skb->data; + buffer->element[element].length = hdr_len; + buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG; + buf->next_element_to_fill++; + skb->data += hdr_len; + skb->len -= hdr_len; + large_send = 1; + } if (skb_shinfo(skb)->nr_frags == 0) - __qeth_fill_buffer(skb, buffer, + __qeth_fill_buffer(skb, buffer, large_send, (int *)&buf->next_element_to_fill); else - __qeth_fill_buffer_frag(skb, buffer, 0, + __qeth_fill_buffer_frag(skb, buffer, large_send, (int *)&buf->next_element_to_fill); if (!queue->do_pack) { @@ -4224,6 +4250,25 @@ out: return rc; } +static inline int +qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) +{ + int elements_needed = 0; + + if (skb_shinfo(skb)->nr_frags > 0) { + elements_needed = (skb_shinfo(skb)->nr_frags + 1); + } + if (elements_needed == 0 ) + elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) + + skb->len) >> PAGE_SHIFT); + if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ + PRINT_ERR("qeth_do_send_packet: invalid size of " + "IP packet. Discarded."); + return 0; + } + return elements_needed; +} + static inline int qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) { @@ -4266,19 +4311,25 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) if (skb_shinfo(skb)->tso_size) large_send = card->options.large_send; - if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))){ - QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); - return rc; - } /*are we able to do TSO ? If so ,prepare and send it from here */ if ((large_send == QETH_LARGE_SEND_TSO) && (cast_type == RTN_UNSPEC)) { - rc = qeth_tso_send_packet(card, skb, queue, - ipv, cast_type); - goto do_statistics; + rc = qeth_tso_prepare_packet(card, skb, ipv, cast_type); + if (rc) { + card->stats.tx_dropped++; + card->stats.tx_errors++; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + elements_needed++; + } else { + if ((rc = qeth_prepare_skb(card, &skb, &hdr, ipv))) { + QETH_DBF_TEXT_(trace, 4, "pskbe%d", rc); + return rc; + } + qeth_fill_header(card, hdr, skb, ipv, cast_type); } - qeth_fill_header(card, hdr, skb, ipv, cast_type); if (large_send == QETH_LARGE_SEND_EDDP) { ctx = qeth_eddp_create_context(card, skb, hdr); if (ctx == NULL) { @@ -4286,7 +4337,7 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) return -EINVAL; } } else { - elements_needed = qeth_get_elements_no(card,(void*) hdr, skb); + elements_needed += qeth_get_elements_no(card,(void*) hdr, skb); if (!elements_needed) return -EINVAL; } @@ -4297,12 +4348,12 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb) else rc = qeth_do_send_packet_fast(card, queue, skb, hdr, elements_needed, ctx); -do_statistics: if (!rc){ card->stats.tx_packets++; card->stats.tx_bytes += skb->len; #ifdef CONFIG_QETH_PERF_STATS - if (skb_shinfo(skb)->tso_size) { + if (skb_shinfo(skb)->tso_size && + !(large_send == QETH_LARGE_SEND_NO)) { card->perf_stats.large_send_bytes += skb->len; card->perf_stats.large_send_cnt++; } @@ -7199,7 +7250,7 @@ qeth_wait_for_threads(struct qeth_card *card, unsigned long threads) } static int -qeth_stop_card(struct qeth_card *card) +qeth_stop_card(struct qeth_card *card, int recovery_mode) { int rc = 0; @@ -7212,9 +7263,13 @@ qeth_stop_card(struct qeth_card *card) if (card->read.state == CH_STATE_UP && card->write.state == CH_STATE_UP && (card->state == CARD_STATE_UP)) { - rtnl_lock(); - dev_close(card->dev); - rtnl_unlock(); + if(recovery_mode) { + qeth_stop(card->dev); + } else { + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); + } if (!card->use_hard_stop) { __u8 *mac = &card->dev->dev_addr[0]; rc = qeth_layer2_send_delmac(card, mac); @@ -7386,13 +7441,17 @@ qeth_register_netdev(struct qeth_card *card) } static void -qeth_start_again(struct qeth_card *card) +qeth_start_again(struct qeth_card *card, int recovery_mode) { QETH_DBF_TEXT(setup ,2, "startag"); - rtnl_lock(); - dev_open(card->dev); - rtnl_unlock(); + if(recovery_mode) { + qeth_open(card->dev); + } else { + rtnl_lock(); + dev_open(card->dev); + rtnl_unlock(); + } /* this also sets saved unicast addresses */ qeth_set_multicast_list(card->dev); } @@ -7449,7 +7508,7 @@ static void qeth_make_parameters_consistent(struct qeth_card *card) static int -qeth_set_online(struct ccwgroup_device *gdev) +__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode) { struct qeth_card *card = gdev->dev.driver_data; int rc = 0; @@ -7509,12 +7568,12 @@ qeth_set_online(struct ccwgroup_device *gdev) * we can also use this state for recovery purposes*/ qeth_set_allowed_threads(card, 0xffffffff, 0); if (recover_flag == CARD_STATE_RECOVER) - qeth_start_again(card); + qeth_start_again(card, recovery_mode); qeth_notify_processes(); return 0; out_remove: card->use_hard_stop = 1; - qeth_stop_card(card); + qeth_stop_card(card, 0); ccw_device_set_offline(CARD_DDEV(card)); ccw_device_set_offline(CARD_WDEV(card)); ccw_device_set_offline(CARD_RDEV(card)); @@ -7525,6 +7584,12 @@ out_remove: return -ENODEV; } +static int +qeth_set_online(struct ccwgroup_device *gdev) +{ + return __qeth_set_online(gdev, 0); +} + static struct ccw_device_id qeth_ids[] = { {CCW_DEVICE(0x1731, 0x01), driver_info:QETH_CARD_TYPE_OSAE}, {CCW_DEVICE(0x1731, 0x05), driver_info:QETH_CARD_TYPE_IQD}, diff --git a/drivers/s390/net/qeth_tso.c b/drivers/s390/net/qeth_tso.c deleted file mode 100644 index 4e58f19cb71c..000000000000 --- a/drivers/s390/net/qeth_tso.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * linux/drivers/s390/net/qeth_tso.c ($Revision: 1.7 $) - * - * Header file for qeth TCP Segmentation Offload support. - * - * Copyright 2004 IBM Corporation - * - * Author(s): Frank Pavlic - * - * $Revision: 1.7 $ $Date: 2005/04/01 21:40:41 $ - * - */ - -#include -#include -#include -#include -#include -#include "qeth.h" -#include "qeth_mpc.h" -#include "qeth_tso.h" - -/** - * skb already partially prepared - * classic qdio header in skb->data - * */ -static inline struct qeth_hdr_tso * -qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) -{ - int rc = 0; - - QETH_DBF_TEXT(trace, 5, "tsoprsk"); - rc = qeth_realloc_headroom(card, skb,sizeof(struct qeth_hdr_ext_tso)); - if (rc) - return NULL; - - return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_ext_tso)); -} - -/** - * fill header for a TSO packet - */ -static inline void -qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) -{ - struct qeth_hdr_tso *hdr; - struct tcphdr *tcph; - struct iphdr *iph; - - QETH_DBF_TEXT(trace, 5, "tsofhdr"); - - hdr = (struct qeth_hdr_tso *) skb->data; - iph = skb->nh.iph; - tcph = skb->h.th; - /*fix header to TSO values ...*/ - hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; - /*set values which are fix for the first approach ...*/ - hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); - hdr->ext.imb_hdr_no = 1; - hdr->ext.hdr_type = 1; - hdr->ext.hdr_version = 1; - hdr->ext.hdr_len = 28; - /*insert non-fix values */ - hdr->ext.mss = skb_shinfo(skb)->tso_size; - hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); - hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - - sizeof(struct qeth_hdr_tso)); -} - -/** - * change some header values as requested by hardware - */ -static inline void -qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb) -{ - struct iphdr *iph; - struct ipv6hdr *ip6h; - struct tcphdr *tcph; - - iph = skb->nh.iph; - ip6h = skb->nh.ipv6h; - tcph = skb->h.th; - - tcph->check = 0; - if (skb->protocol == ETH_P_IPV6) { - ip6h->payload_len = 0; - tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, - 0, IPPROTO_TCP, 0); - return; - } - /*OSA want us to set these values ...*/ - tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, - 0, IPPROTO_TCP, 0); - iph->tot_len = 0; - iph->check = 0; -} - -static inline struct qeth_hdr_tso * -qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb, - int ipv, int cast_type) -{ - struct qeth_hdr_tso *hdr; - int rc = 0; - - QETH_DBF_TEXT(trace, 5, "tsoprep"); - - /*get headroom for tso qdio header */ - hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb); - if (hdr == NULL) { - QETH_DBF_TEXT_(trace, 4, "2err%d", rc); - return NULL; - } - memset(hdr, 0, sizeof(struct qeth_hdr_tso)); - /*fill first 32 bytes of qdio header as used - *FIXME: TSO has two struct members - * with different names but same size - * */ - qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type); - qeth_tso_fill_header(card, skb); - qeth_tso_set_tcpip_header(card, skb); - return hdr; -} - -static inline int -qeth_tso_get_queue_buffer(struct qeth_qdio_out_q *queue) -{ - struct qeth_qdio_out_buffer *buffer; - int flush_cnt = 0; - - QETH_DBF_TEXT(trace, 5, "tsobuf"); - - /* force to non-packing*/ - if (queue->do_pack) - queue->do_pack = 0; - buffer = &queue->bufs[queue->next_buf_to_fill]; - /* get a new buffer if current is already in use*/ - if ((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) && - (buffer->next_element_to_fill > 0)) { - atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED); - queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % - QDIO_MAX_BUFFERS_PER_Q; - flush_cnt++; - } - return flush_cnt; -} - - -static inline int -qeth_tso_fill_buffer(struct qeth_qdio_out_buffer *buf, - struct sk_buff *skb) -{ - int length, length_here, element; - int hdr_len; - struct qdio_buffer *buffer; - struct qeth_hdr_tso *hdr; - char *data; - - QETH_DBF_TEXT(trace, 3, "tsfilbuf"); - - /*increment user count and queue skb ...*/ - atomic_inc(&skb->users); - skb_queue_tail(&buf->skb_list, skb); - - /*initialize all variables...*/ - buffer = buf->buffer; - hdr = (struct qeth_hdr_tso *)skb->data; - hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len; - data = skb->data + hdr_len; - length = skb->len - hdr_len; - element = buf->next_element_to_fill; - /*fill first buffer entry only with header information */ - buffer->element[element].addr = skb->data; - buffer->element[element].length = hdr_len; - buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG; - buf->next_element_to_fill++; - /*check if we have frags ...*/ - if (skb_shinfo(skb)->nr_frags > 0) { - skb->len = length; - skb->data = data; - __qeth_fill_buffer_frag(skb, buffer,1, - (int *)&buf->next_element_to_fill); - goto out; - } - - /*... if not, use this */ - element++; - while (length > 0) { - /* length_here is the remaining amount of data in this page */ - length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE); - if (length < length_here) - length_here = length; - buffer->element[element].addr = data; - buffer->element[element].length = length_here; - length -= length_here; - if (!length) - buffer->element[element].flags = - SBAL_FLAGS_LAST_FRAG; - else - buffer->element[element].flags = - SBAL_FLAGS_MIDDLE_FRAG; - data += length_here; - element++; - } - buf->next_element_to_fill = element; -out: - /*prime buffer now ...*/ - atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED); - return 1; -} - -int -qeth_tso_send_packet(struct qeth_card *card, struct sk_buff *skb, - struct qeth_qdio_out_q *queue, int ipv, int cast_type) -{ - int flush_cnt = 0; - struct qeth_hdr_tso *hdr; - struct qeth_qdio_out_buffer *buffer; - int start_index; - - QETH_DBF_TEXT(trace, 3, "tsosend"); - - if (!(hdr = qeth_tso_prepare_packet(card, skb, ipv, cast_type))) - return -ENOMEM; - /*check if skb fits in one SBAL ...*/ - if (!(qeth_get_elements_no(card, (void*)hdr, skb))) - return -EINVAL; - /*lock queue, force switching to non-packing and send it ...*/ - while (atomic_compare_and_swap(QETH_OUT_Q_UNLOCKED, - QETH_OUT_Q_LOCKED, - &queue->state)); - start_index = queue->next_buf_to_fill; - buffer = &queue->bufs[queue->next_buf_to_fill]; - /*check if card is too busy ...*/ - if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY){ - card->stats.tx_dropped++; - goto out; - } - /*let's force to non-packing and get a new SBAL*/ - flush_cnt += qeth_tso_get_queue_buffer(queue); - buffer = &queue->bufs[queue->next_buf_to_fill]; - if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) { - card->stats.tx_dropped++; - goto out; - } - flush_cnt += qeth_tso_fill_buffer(buffer, skb); - queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) % - QDIO_MAX_BUFFERS_PER_Q; -out: - atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED); - if (flush_cnt) - qeth_flush_buffers(queue, 0, start_index, flush_cnt); - /*do some statistics */ - card->stats.tx_packets++; - card->stats.tx_bytes += skb->len; - return 0; -} diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index ff585ae49b6c..ad33e6f466f1 100644 --- a/drivers/s390/net/qeth_tso.h +++ b/drivers/s390/net/qeth_tso.h @@ -1,5 +1,5 @@ /* - * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.5 $) + * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.7 $) * * Header file for qeth TCP Segmentation Offload support. * @@ -7,97 +7,148 @@ * * Author(s): Frank Pavlic * - * $Revision: 1.5 $ $Date: 2005/04/01 21:40:41 $ + * $Revision: 1.7 $ $Date: 2005/05/04 20:19:18 $ * */ #ifndef __QETH_TSO_H__ #define __QETH_TSO_H__ +#include +#include +#include +#include +#include +#include "qeth.h" +#include "qeth_mpc.h" -extern int -qeth_tso_send_packet(struct qeth_card *, struct sk_buff *, - struct qeth_qdio_out_q *, int , int); -struct qeth_hdr_ext_tso { - __u16 hdr_tot_len; - __u8 imb_hdr_no; - __u8 reserved; - __u8 hdr_type; - __u8 hdr_version; - __u16 hdr_len; - __u32 payload_len; - __u16 mss; - __u16 dg_hdr_len; - __u8 padding[16]; -} __attribute__ ((packed)); +static inline struct qeth_hdr_tso * +qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb) +{ + QETH_DBF_TEXT(trace, 5, "tsoprsk"); + return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso)); +} + +/** + * fill header for a TSO packet + */ +static inline void +qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb) +{ + struct qeth_hdr_tso *hdr; + struct tcphdr *tcph; + struct iphdr *iph; -struct qeth_hdr_tso { - struct qeth_hdr hdr; /*hdr->hdr.l3.xxx*/ - struct qeth_hdr_ext_tso ext; -} __attribute__ ((packed)); + QETH_DBF_TEXT(trace, 5, "tsofhdr"); + + hdr = (struct qeth_hdr_tso *) skb->data; + iph = skb->nh.iph; + tcph = skb->h.th; + /*fix header to TSO values ...*/ + hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO; + /*set values which are fix for the first approach ...*/ + hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso); + hdr->ext.imb_hdr_no = 1; + hdr->ext.hdr_type = 1; + hdr->ext.hdr_version = 1; + hdr->ext.hdr_len = 28; + /*insert non-fix values */ + hdr->ext.mss = skb_shinfo(skb)->tso_size; + hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4); + hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len - + sizeof(struct qeth_hdr_tso)); +} + +/** + * change some header values as requested by hardware + */ +static inline void +qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb) +{ + struct iphdr *iph; + struct ipv6hdr *ip6h; + struct tcphdr *tcph; + + iph = skb->nh.iph; + ip6h = skb->nh.ipv6h; + tcph = skb->h.th; + + tcph->check = 0; + if (skb->protocol == ETH_P_IPV6) { + ip6h->payload_len = 0; + tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, + 0, IPPROTO_TCP, 0); + return; + } + /*OSA want us to set these values ...*/ + tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, + 0, IPPROTO_TCP, 0); + iph->tot_len = 0; + iph->check = 0; +} -/*some helper functions*/ static inline int -qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) +qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb, + int ipv, int cast_type) { - int elements_needed = 0; + struct qeth_hdr_tso *hdr; - if (skb_shinfo(skb)->nr_frags > 0) - elements_needed = (skb_shinfo(skb)->nr_frags + 1); - if (elements_needed == 0 ) - elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) - + skb->len) >> PAGE_SHIFT); - if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ - PRINT_ERR("qeth_do_send_packet: invalid size of " - "IP packet. Discarded."); - return 0; - } - return elements_needed; + QETH_DBF_TEXT(trace, 5, "tsoprep"); + + hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb); + if (hdr == NULL) { + QETH_DBF_TEXT(trace, 4, "tsoperr"); + return -ENOMEM; + } + memset(hdr, 0, sizeof(struct qeth_hdr_tso)); + /*fill first 32 bytes of qdio header as used + *FIXME: TSO has two struct members + * with different names but same size + * */ + qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type); + qeth_tso_fill_header(card, skb); + qeth_tso_set_tcpip_header(card, skb); + return 0; } static inline void __qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer, int is_tso, int *next_element_to_fill) { - int length = skb->len; struct skb_frag_struct *frag; int fragno; unsigned long addr; - int element; - int first_lap = 1; - - fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */ - element = *next_element_to_fill + fragno; - while (length > 0) { - if (fragno > 0) { - frag = &skb_shinfo(skb)->frags[fragno - 1]; - addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + - frag->page_offset; - buffer->element[element].addr = (char *)addr; - buffer->element[element].length = frag->size; - length -= frag->size; - if (first_lap) - buffer->element[element].flags = - SBAL_FLAGS_LAST_FRAG; - else - buffer->element[element].flags = - SBAL_FLAGS_MIDDLE_FRAG; - } else { - buffer->element[element].addr = skb->data; - buffer->element[element].length = length; - length = 0; - if (is_tso) - buffer->element[element].flags = - SBAL_FLAGS_MIDDLE_FRAG; - else - buffer->element[element].flags = - SBAL_FLAGS_FIRST_FRAG; - } - element--; - fragno--; - first_lap = 0; + int element, cnt, dlen; + + fragno = skb_shinfo(skb)->nr_frags; + element = *next_element_to_fill; + dlen = 0; + + if (is_tso) + buffer->element[element].flags = + SBAL_FLAGS_MIDDLE_FRAG; + else + buffer->element[element].flags = + SBAL_FLAGS_FIRST_FRAG; + if ( (dlen = (skb->len - skb->data_len)) ) { + buffer->element[element].addr = skb->data; + buffer->element[element].length = dlen; + element++; } - *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1; + for (cnt = 0; cnt < fragno; cnt++) { + frag = &skb_shinfo(skb)->frags[cnt]; + addr = (page_to_pfn(frag->page) << PAGE_SHIFT) + + frag->page_offset; + buffer->element[element].addr = (char *)addr; + buffer->element[element].length = frag->size; + if (cnt < (fragno - 1)) + buffer->element[element].flags = + SBAL_FLAGS_MIDDLE_FRAG; + else + buffer->element[element].flags = + SBAL_FLAGS_LAST_FRAG; + element++; + } + *next_element_to_fill = element; } - #endif /* __QETH_TSO_H__ */ -- cgit v1.2.2 From f27eff1ffd65236b8e421188f76ad1b0b94e06eb Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 12 May 2005 17:47:27 +1000 Subject: [PATCH] iseries_veth: Don't send packets to LPARs which aren't up Hi Andrew, Jeff, The iseries_veth driver has a logic bug which means it will erroneously send packets to LPARs for which we don't have a connection. This usually isn't a big problem because the Hypervisor call fails gracefully and we return, but if packets are TX'ed during the negotiation of the connection bad things might happen. Regardless, the right thing is to bail early if we know there's no connection. Signed-off-by: Michael Ellerman --- drivers/net/iseries_veth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 855f8b2cf13b..7d0ef2969b4e 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -924,7 +924,7 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp, spin_lock_irqsave(&cnx->lock, flags); - if (! cnx->state & VETH_STATE_READY) + if (! (cnx->state & VETH_STATE_READY)) goto drop; if ((skb->len - 14) > VETH_MAX_MTU) -- cgit v1.2.2 From eb235aef724568ae15af831968000cf9a3974b26 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 12 May 2005 17:53:18 +1000 Subject: [PATCH] iseries_veth: Set dev->trans_start so watchdog timer works right Hi Andrew, Jeff, The iseries_veth driver doesn't set dev->trans_start in it's TX path. This will cause the net device watchdog timer to fire earlier than we want it to, which causes the driver to needlessly reset its connections to other LPARs. Signed-off-by: Michael Ellerman --- drivers/net/iseries_veth.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 7d0ef2969b4e..1e869df656c1 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1023,6 +1023,8 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) lpmask = veth_transmit_to_many(skb, lpmask, dev); + dev->trans_start = jiffies; + if (! lpmask) { dev_kfree_skb(skb); } else { -- cgit v1.2.2 From 41664c03f6c96a1f8a91714309b36f1b5ca85610 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 12 May 2005 17:55:08 +1000 Subject: [PATCH] iseries_veth: Don't leak skbs in RX path Hi Andrew, Jeff, Under some strange circumstances the iseries_veth driver can leak skbs. Fix is simply to call dev_kfree_skb() in the right place. Fix up the comment as well. Signed-off-by: Michael Ellerman --- drivers/net/iseries_veth.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 1e869df656c1..1edecb10993d 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1264,13 +1264,18 @@ static void veth_receive(struct veth_lpar_connection *cnx, vlan = skb->data[9]; dev = veth_dev[vlan]; - if (! dev) - /* Some earlier versions of the driver sent - broadcasts down all connections, even to - lpars that weren't on the relevant vlan. - So ignore packets belonging to a vlan we're - not on. */ + if (! dev) { + /* + * Some earlier versions of the driver sent + * broadcasts down all connections, even to lpars + * that weren't on the relevant vlan. So ignore + * packets belonging to a vlan we're not on. + * We can also be here if we receive packets while + * the driver is going down, because then dev is NULL. + */ + dev_kfree_skb_irq(skb); continue; + } port = (struct veth_port *)dev->priv; dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000; -- cgit v1.2.2 From b2e0852e1eee7c445b1789bef41204b64f981102 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 12 May 2005 18:09:45 +1000 Subject: [PATCH] iseries_veth: Cleanup skbs to prevent unregister_netdevice() hanging Hi Andrew, Jeff, The iseries_veth driver is badly behaved in that it will keep TX packets hanging around forever if they're not ACK'ed and the queue never fills up. This causes the unregister_netdevice code to wait forever when we try to take the device down, because there's still skbs around with references to our struct net_device. There's already code to cleanup any un-ACK'ed packets in veth_stop_connection() but it's being called after we unregister the net_device, which is too late. The fix is to rearrange the module exit function so that we cleanup any outstanding skbs and then unregister the driver. Signed-off-by: Michael Ellerman --- drivers/net/iseries_veth.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 1edecb10993d..13ed8dc1e91d 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -1388,18 +1388,25 @@ void __exit veth_module_cleanup(void) { int i; - vio_unregister_driver(&veth_driver); + /* Stop the queues first to stop any new packets being sent. */ + for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) + if (veth_dev[i]) + netif_stop_queue(veth_dev[i]); + /* Stop the connections before we unregister the driver. This + * ensures there's no skbs lying around holding the device open. */ for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) veth_stop_connection(i); HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan); /* Hypervisor callbacks may have scheduled more work while we - * were destroying connections. Now that we've disconnected from + * were stoping connections. Now that we've disconnected from * the hypervisor make sure everything's finished. */ flush_scheduled_work(); + vio_unregister_driver(&veth_driver); + for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) veth_destroy_connection(i); -- cgit v1.2.2 From 22c6d143f33f10721216a8cfa3a83f7edfc2bd4e Mon Sep 17 00:00:00 2001 From: Manfred Spraul Date: Tue, 19 Apr 2005 21:17:09 +0200 Subject: [PATCH] forcedeth: Update error handling Ayaz wrote an update to the error handling for forcedeth (which I modified heavily, thus all bugs are mine): The ERROR4 bit is not a fatal error, it just indicates a mismatch between the actual packet len and the len according to the 802.3 header. The patch adds proper handling. The patch also removes the code that drops all packets with RX_ERROR & (!RX_FRAMINGERR): ERROR4 errors are also not fatal. --- drivers/net/forcedeth.c | 93 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index c93f3d08dc42..4ebcd052e150 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -81,6 +81,7 @@ * cause DMA to kfree'd memory. * 0.31: 14 Nov 2004: ethtool support for getting/setting link * capabilities. + * 0.32: 16 Apr 2005: RX_ERROR4 handling added. * * Known bugs: * We suspect that on some hardware no TX done interrupts are generated. @@ -92,7 +93,7 @@ * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few * superfluous timer interrupts from the nic. */ -#define FORCEDETH_VERSION "0.31" +#define FORCEDETH_VERSION "0.32" #define DRV_NAME "forcedeth" #include @@ -109,6 +110,7 @@ #include #include #include +#include #include #include @@ -1013,6 +1015,59 @@ static void nv_tx_timeout(struct net_device *dev) spin_unlock_irq(&np->lock); } +/* + * Called when the nic notices a mismatch between the actual data len on the + * wire and the len indicated in the 802 header + */ +static int nv_getlen(struct net_device *dev, void *packet, int datalen) +{ + int hdrlen; /* length of the 802 header */ + int protolen; /* length as stored in the proto field */ + + /* 1) calculate len according to header */ + if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == __constant_htons(ETH_P_8021Q)) { + protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto ); + hdrlen = VLAN_HLEN; + } else { + protolen = ntohs( ((struct ethhdr *)packet)->h_proto); + hdrlen = ETH_HLEN; + } + dprintk(KERN_DEBUG "%s: nv_getlen: datalen %d, protolen %d, hdrlen %d\n", + dev->name, datalen, protolen, hdrlen); + if (protolen > ETH_DATA_LEN) + return datalen; /* Value in proto field not a len, no checks possible */ + + protolen += hdrlen; + /* consistency checks: */ + if (datalen > ETH_ZLEN) { + if (datalen >= protolen) { + /* more data on wire than in 802 header, trim of + * additional data. + */ + dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n", + dev->name, protolen); + return protolen; + } else { + /* less data on wire than mentioned in header. + * Discard the packet. + */ + dprintk(KERN_DEBUG "%s: nv_getlen: discarding long packet.\n", + dev->name); + return -1; + } + } else { + /* short packet. Accept only if 802 values are also short */ + if (protolen > ETH_ZLEN) { + dprintk(KERN_DEBUG "%s: nv_getlen: discarding short packet.\n", + dev->name); + return -1; + } + dprintk(KERN_DEBUG "%s: nv_getlen: accepting %d bytes.\n", + dev->name, datalen); + return datalen; + } +} + static void nv_rx_process(struct net_device *dev) { struct fe_priv *np = get_nvpriv(dev); @@ -1064,7 +1119,7 @@ static void nv_rx_process(struct net_device *dev) np->stats.rx_errors++; goto next_pkt; } - if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4)) { + if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) { np->stats.rx_errors++; goto next_pkt; } @@ -1078,22 +1133,24 @@ static void nv_rx_process(struct net_device *dev) np->stats.rx_errors++; goto next_pkt; } - if (Flags & NV_RX_ERROR) { - /* framing errors are soft errors, the rest is fatal. */ - if (Flags & NV_RX_FRAMINGERR) { - if (Flags & NV_RX_SUBSTRACT1) { - len--; - } - } else { + if (Flags & NV_RX_ERROR4) { + len = nv_getlen(dev, np->rx_skbuff[i]->data, len); + if (len < 0) { np->stats.rx_errors++; goto next_pkt; } } + /* framing errors are soft errors. */ + if (Flags & NV_RX_FRAMINGERR) { + if (Flags & NV_RX_SUBSTRACT1) { + len--; + } + } } else { if (!(Flags & NV_RX2_DESCRIPTORVALID)) goto next_pkt; - if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4)) { + if (Flags & (NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3)) { np->stats.rx_errors++; goto next_pkt; } @@ -1107,17 +1164,19 @@ static void nv_rx_process(struct net_device *dev) np->stats.rx_errors++; goto next_pkt; } - if (Flags & NV_RX2_ERROR) { - /* framing errors are soft errors, the rest is fatal. */ - if (Flags & NV_RX2_FRAMINGERR) { - if (Flags & NV_RX2_SUBSTRACT1) { - len--; - } - } else { + if (Flags & NV_RX2_ERROR4) { + len = nv_getlen(dev, np->rx_skbuff[i]->data, len); + if (len < 0) { np->stats.rx_errors++; goto next_pkt; } } + /* framing errors are soft errors */ + if (Flags & NV_RX2_FRAMINGERR) { + if (Flags & NV_RX2_SUBSTRACT1) { + len--; + } + } Flags &= NV_RX2_CHECKSUMMASK; if (Flags == NV_RX2_CHECKSUMOK1 || Flags == NV_RX2_CHECKSUMOK2 || -- cgit v1.2.2 From e885b5e83965c320e8eff1ec3ebfbf821b375568 Mon Sep 17 00:00:00 2001 From: "simon@thekelleys.org.uk" Date: Sat, 7 May 2005 21:33:31 +0100 Subject: [PATCH] atmel wireless Below is a one-liner for the atmel wireless driver, just adding another card to the table. --- drivers/net/wireless/atmel_cs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index a91b507e0a7a..a4ed28d9c783 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -321,6 +321,7 @@ static struct { { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" }, { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" }, { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" }, + { 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" }, { 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" }, { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" }, { 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" }, -- cgit v1.2.2 From 760f86d78d92f39e2ceb55b40f0885eb755c8c2f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 16 Apr 2005 16:24:16 +1000 Subject: [PATCH] Fw: [Bugme-new] [Bug 4482] New: natsemi: incorrect initialization of IPv6 Neighbor-discovery multicast On Wed, Apr 13, 2005 at 05:36:42PM +0000, Andrew Morton wrote: > Summary: natsemi: incorrect initialization of IPv6 Neighbor- > discovery multicast I've got a pair of FA312 cards and this problem has bothered me for ages. This has finally prompted me to do something about it :) Turns out that somebody wasn't following the documentation. We were doing 16-bit writes to 32-bit registers which led to some addresses working and others not so lucky. This patch should fix the problem. Signed-off-by: Herbert Xu --- drivers/net/natsemi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 223bdadd4c0d..babb59e146ea 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -2433,9 +2433,9 @@ static void __set_rx_mode(struct net_device *dev) rx_mode = RxFilterEnable | AcceptBroadcast | AcceptMulticast | AcceptMyPhys; for (i = 0; i < 64; i += 2) { - writew(HASH_TABLE + i, ioaddr + RxFilterAddr); - writew((mc_filter[i+1]<<8) + mc_filter[i], - ioaddr + RxFilterData); + writel(HASH_TABLE + i, ioaddr + RxFilterAddr); + writel((mc_filter[i + 1] << 8) + mc_filter[i], + ioaddr + RxFilterData); } } writel(rx_mode, ioaddr + RxFilterAddr); -- cgit v1.2.2 From 41480af27a85d6008d9e11db8bc2730407c25e1d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 10 May 2005 09:45:51 -0400 Subject: [PATCH] wireless/airo: WEXT and quality corrections This patch brings the airo driver into line with the current WEXT specification of signal quality. It also fixes the values used to determine signal quality and level for MPI & PCMCIA 350 cards. It turns out that BSSListRid.rssi was actually in dBm for 350 series cards, and that we can use the normalized signal strength reported by the card as our "quality" value, on a scale of 0 - 100. Since signal level values are in dBm for this driver, max_qual->level MUST be 0, as specified in the WEXT spec. This patch also uses the IW_QUAL constants new in WEXT version 17. Signed-off-by: Dan Williams --- drivers/net/wireless/airo.c | 150 ++++++++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 463c789cdc77..fb10a2db63ad 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -754,7 +754,7 @@ typedef struct { u8 zero; u8 ssidLen; u8 ssid[32]; - u16 rssi; + u16 dBm; #define CAP_ESS (1<<0) #define CAP_IBSS (1<<1) #define CAP_PRIVACY (1<<4) @@ -1125,6 +1125,9 @@ static int micsetup(struct airo_info *ai); static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); +static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi); +static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm); + #include #endif @@ -1713,6 +1716,7 @@ static int readBSSListRid(struct airo_info *ai, int first, list->fh.dwell = le16_to_cpu(list->fh.dwell); list->dsChannel = le16_to_cpu(list->dsChannel); list->atimWindow = le16_to_cpu(list->atimWindow); + list->dBm = le16_to_cpu(list->dBm); return rc; } @@ -3245,7 +3249,10 @@ badrx: wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; else wstats.level = (hdr.rssi[1] + 321) / 2; - wstats.updated = 3; + wstats.noise = apriv->wstats.qual.noise; + wstats.updated = IW_QUAL_LEVEL_UPDATED + | IW_QUAL_QUAL_UPDATED + | IW_QUAL_NOISE_UPDATED; /* Update spy records */ wireless_spy_update(dev, sa, &wstats); } @@ -3588,7 +3595,10 @@ void mpi_receive_802_11 (struct airo_info *ai) wstats.level = 0x100 - ai->rssi[hdr.rssi[1]].rssidBm; else wstats.level = (hdr.rssi[1] + 321) / 2; - wstats.updated = 3; + wstats.noise = ai->wstats.qual.noise; + wstats.updated = IW_QUAL_QUAL_UPDATED + | IW_QUAL_LEVEL_UPDATED + | IW_QUAL_NOISE_UPDATED; /* Update spy records */ wireless_spy_update(ai->dev, sa, &wstats); } @@ -3679,7 +3689,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock) status = PC4500_readrid(ai,RID_RSSI,&rssi_rid,sizeof(rssi_rid),lock); if ( status == SUCCESS ) { if (ai->rssi || (ai->rssi = kmalloc(512, GFP_KERNEL)) != NULL) - memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); + memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */ } else { if (ai->rssi) { @@ -5348,7 +5358,7 @@ static int proc_BSSList_open( struct inode *inode, struct file *file ) { (int)BSSList_rid.bssid[5], (int)BSSList_rid.ssidLen, BSSList_rid.ssid, - (int)BSSList_rid.rssi); + (int)BSSList_rid.dBm); ptr += sprintf(ptr, " channel = %d %s %s %s %s\n", (int)BSSList_rid.dsChannel, BSSList_rid.cap & CAP_ESS ? "ESS" : "", @@ -5593,6 +5603,29 @@ static void __exit airo_cleanup_module( void ) * would not work at all... - Jean II */ +static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi) +{ + if( !rssi_rid ) + return 0; + + return (0x100 - rssi_rid[rssi].rssidBm); +} + +static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm) +{ + int i; + + if( !rssi_rid ) + return 0; + + for( i = 0; i < 256; i++ ) + if (rssi_rid[i].rssidBm == dbm) + return rssi_rid[i].rssipct; + + return 0; +} + + static int airo_get_quality (StatusRid *status_rid, CapabilityRid *cap_rid) { int quality = 0; @@ -6443,11 +6476,29 @@ static int airo_get_range(struct net_device *dev, } range->num_frequency = k; + range->sensitivity = 65535; + /* Hum... Should put the right values there */ - range->max_qual.qual = airo_get_max_quality(&cap_rid); - range->max_qual.level = 0x100 - 120; /* -120 dBm */ + if (local->rssi) + range->max_qual.qual = 100; /* % */ + else + range->max_qual.qual = airo_get_max_quality(&cap_rid); + range->max_qual.level = 0; /* 0 means we use dBm */ range->max_qual.noise = 0; - range->sensitivity = 65535; + range->max_qual.updated = 0; + + /* Experimental measurements - boundary 11/5.5 Mb/s */ + /* Note : with or without the (local->rssi), results + * are somewhat different. - Jean II */ + if (local->rssi) { + range->avg_qual.qual = 50; /* % */ + range->avg_qual.level = 186; /* -70 dBm */ + } else { + range->avg_qual.qual = airo_get_avg_quality(&cap_rid); + range->avg_qual.level = 176; /* -80 dBm */ + } + range->avg_qual.noise = 0; + range->avg_qual.updated = 0; for(i = 0 ; i < 8 ; i++) { range->bitrate[i] = cap_rid.supportedRates[i] * 500000; @@ -6508,15 +6559,6 @@ static int airo_get_range(struct net_device *dev, range->max_retry = 65535; range->min_r_time = 1024; range->max_r_time = 65535 * 1024; - /* Experimental measurements - boundary 11/5.5 Mb/s */ - /* Note : with or without the (local->rssi), results - * are somewhat different. - Jean II */ - range->avg_qual.qual = airo_get_avg_quality(&cap_rid); - if (local->rssi) - range->avg_qual.level = 186; /* -70 dBm */ - else - range->avg_qual.level = 176; /* -80 dBm */ - range->avg_qual.noise = 0; /* Event capability (kernel + driver) */ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | @@ -6676,12 +6718,18 @@ static int airo_get_aplist(struct net_device *dev, loseSync = 0; memcpy(address[i].sa_data, BSSList.bssid, ETH_ALEN); address[i].sa_family = ARPHRD_ETHER; - if (local->rssi) - qual[i].level = 0x100 - local->rssi[BSSList.rssi].rssidBm; - else - qual[i].level = (BSSList.rssi + 321) / 2; - qual[i].qual = qual[i].noise = 0; - qual[i].updated = 2; + if (local->rssi) { + qual[i].level = 0x100 - BSSList.dBm; + qual[i].qual = airo_dbm_to_pct( local->rssi, BSSList.dBm ); + qual[i].updated = IW_QUAL_QUAL_UPDATED; + } else { + qual[i].level = (BSSList.dBm + 321) / 2; + qual[i].qual = 0; + qual[i].updated = IW_QUAL_QUAL_INVALID; + } + qual[i].noise = local->wstats.qual.noise; + qual[i].updated = IW_QUAL_LEVEL_UPDATED + | IW_QUAL_NOISE_UPDATED; if (BSSList.index == 0xffff) break; } @@ -6760,7 +6808,7 @@ static int airo_set_scan(struct net_device *dev, static inline char *airo_translate_scan(struct net_device *dev, char *current_ev, char *end_buf, - BSSListRid *list) + BSSListRid *bss) { struct airo_info *ai = dev->priv; struct iw_event iwe; /* Temporary buffer */ @@ -6771,22 +6819,22 @@ static inline char *airo_translate_scan(struct net_device *dev, /* First entry *MUST* be the AP MAC address */ iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN); + memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); /* Other entries will be displayed in the order we give them */ /* Add the ESSID */ - iwe.u.data.length = list->ssidLen; + iwe.u.data.length = bss->ssidLen; if(iwe.u.data.length > 32) iwe.u.data.length = 32; iwe.cmd = SIOCGIWESSID; iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid); + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); /* Add mode */ iwe.cmd = SIOCGIWMODE; - capabilities = le16_to_cpu(list->cap); + capabilities = le16_to_cpu(bss->cap); if(capabilities & (CAP_ESS | CAP_IBSS)) { if(capabilities & CAP_ESS) iwe.u.mode = IW_MODE_MASTER; @@ -6797,19 +6845,25 @@ static inline char *airo_translate_scan(struct net_device *dev, /* Add frequency */ iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = le16_to_cpu(list->dsChannel); + iwe.u.freq.m = le16_to_cpu(bss->dsChannel); iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000; iwe.u.freq.e = 1; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); /* Add quality statistics */ iwe.cmd = IWEVQUAL; - if (ai->rssi) - iwe.u.qual.level = 0x100 - ai->rssi[list->rssi].rssidBm; - else - iwe.u.qual.level = (list->rssi + 321) / 2; - iwe.u.qual.noise = 0; - iwe.u.qual.qual = 0; + if (ai->rssi) { + iwe.u.qual.level = 0x100 - bss->dBm; + iwe.u.qual.qual = airo_dbm_to_pct( ai->rssi, bss->dBm ); + iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED; + } else { + iwe.u.qual.level = (bss->dBm + 321) / 2; + iwe.u.qual.qual = 0; + iwe.u.qual.updated = IW_QUAL_QUAL_INVALID; + } + iwe.u.qual.noise = ai->wstats.qual.noise; + iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED + | IW_QUAL_NOISE_UPDATED; current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); /* Add encryption capability */ @@ -6819,7 +6873,7 @@ static inline char *airo_translate_scan(struct net_device *dev, else iwe.u.data.flags = IW_ENCODE_DISABLED; iwe.u.data.length = 0; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, list->ssid); + current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); /* Rate : stuffing multiple values in a single event require a bit * more of magic - Jean II */ @@ -6831,10 +6885,10 @@ static inline char *airo_translate_scan(struct net_device *dev, /* Max 8 values */ for(i = 0 ; i < 8 ; i++) { /* NULL terminated */ - if(list->rates[i] == 0) + if(bss->rates[i] == 0) break; /* Bit rate given in 500 kb/s units (+ 0x80) */ - iwe.u.bitrate.value = ((list->rates[i] & 0x7f) * 500000); + iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000); /* Add new value to event */ current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); } @@ -7153,18 +7207,22 @@ static void airo_read_wireless_stats(struct airo_info *local) /* The status */ local->wstats.status = status_rid.mode; - /* Signal quality and co. But where is the noise level ??? */ - local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); - if (local->rssi) - local->wstats.qual.level = 0x100 - local->rssi[status_rid.sigQuality].rssidBm; - else + /* Signal quality and co */ + if (local->rssi) { + local->wstats.qual.level = airo_rssi_to_dbm( local->rssi, status_rid.sigQuality ); + /* normalizedSignalStrength appears to be a percentage */ + local->wstats.qual.qual = status_rid.normalizedSignalStrength; + } else { local->wstats.qual.level = (status_rid.normalizedSignalStrength + 321) / 2; + local->wstats.qual.qual = airo_get_quality(&status_rid, &cap_rid); + } + local->wstats.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED; if (status_rid.len >= 124) { - local->wstats.qual.noise = 256 - status_rid.noisedBm; - local->wstats.qual.updated = 7; + local->wstats.qual.noise = 0x100 - status_rid.noisedBm; + local->wstats.qual.updated |= IW_QUAL_NOISE_UPDATED; } else { local->wstats.qual.noise = 0; - local->wstats.qual.updated = 3; + local->wstats.qual.updated |= IW_QUAL_NOISE_INVALID; } /* Packets discarded in the wireless adapter due to wireless -- cgit v1.2.2 From 1bcd315362e215a72b56d1330bbf32f1c74eefb5 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Fri, 29 Apr 2005 14:51:17 -0700 Subject: [PATCH] pcnet32: fix resource leak with loopback test When running the loopback test, resources are not properly released on completion. This patch frees all transmit resources after running the loopback test. Tested on ia32 and ppc64 hardware. Signed-off-by: Don Fry --- drivers/net/pcnet32.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 17947e6c8793..13f114876965 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -22,8 +22,8 @@ *************************************************************************/ #define DRV_NAME "pcnet32" -#define DRV_VERSION "1.30i" -#define DRV_RELDATE "06.28.2004" +#define DRV_VERSION "1.30j" +#define DRV_RELDATE "29.04.2005" #define PFX DRV_NAME ": " static const char *version = @@ -256,6 +256,7 @@ static int homepna[MAX_UNITS]; * homepna for selecting HomePNA mode for PCNet/Home 79C978. * v1.30h 24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32. * v1.30i 28 Jun 2004 Don Fry change to use module_param. + * v1.30j 29 Apr 2005 Don Fry fix skb/map leak with loopback test. */ @@ -395,6 +396,7 @@ static void pcnet32_led_blink_callback(struct net_device *dev); static int pcnet32_get_regs_len(struct net_device *dev); static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *ptr); +static void pcnet32_purge_tx_ring(struct net_device *dev); enum pci_flags_bit { PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4, @@ -785,6 +787,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t *data1) } clean_up: + pcnet32_purge_tx_ring(dev); x = a->read_csr(ioaddr, 15) & 0xFFFF; a->write_csr(ioaddr, 15, (x & ~0x0044)); /* reset bits 6 and 2 */ -- cgit v1.2.2 From 6da0f685935e13458a2206ac872d0d3c67a52f65 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 30 Apr 2005 13:52:49 +0200 Subject: [PATCH] SIS900 must select MII This patch fixes the following compile error caused by bk-netdev: <-- snip --> ... LD .tmp_vmlinux1 drivers/built-in.o(.text+0x98528): In function `sis900_get_settings': : undefined reference to `mii_ethtool_gset' drivers/built-in.o(.text+0x98538): In function `sis900_set_settings': : undefined reference to `mii_ethtool_sset' drivers/built-in.o(.text+0x98517): In function `sis900_get_link': : undefined reference to `mii_link_ok' drivers/built-in.o(.text+0x98547): In function `sis900_nway_reset': : undefined reference to `mii_nway_restart' make: *** [.tmp_vmlinux1] Error 1 <-- snip --> Signed-off-by: Adrian Bunk Signed-off-by: Daniele Venzano --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3a0a55b62aaf..7c5c1acd1474 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1555,6 +1555,7 @@ config SIS900 tristate "SiS 900/7016 PCI Fast Ethernet Adapter support" depends on NET_PCI && PCI select CRC32 + select MII ---help--- This is a driver for the Fast Ethernet PCI network cards based on the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in -- cgit v1.2.2 From 15efa9bb2d4da7cd9feb1c67fcf3d9e0e1bd00c6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 4 May 2005 15:33:11 -0700 Subject: [PATCH] tlan: restore deleted module parameters. The module parameter values got lost in the conversion to the new module_param interface. This should fix it. Signed-off-by: Stephen Hemminger Index: tlan/drivers/net/tlan.c =================================================================== --- drivers/net/tlan.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index a7ffa64502dd..f0851c424097 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -193,6 +193,12 @@ static int aui[MAX_TLAN_BOARDS]; static int duplex[MAX_TLAN_BOARDS]; static int speed[MAX_TLAN_BOARDS]; static int boards_found; +module_param_array(aui, int, NULL, 0); +module_param_array(duplex, int, NULL, 0); +module_param_array(speed, int, NULL, 0); +MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)"); +MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)"); +MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)"); MODULE_AUTHOR("Maintainer: Samuel Chessman "); MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters"); @@ -204,8 +210,13 @@ MODULE_LICENSE("GPL"); /* Turn on debugging. See Documentation/networking/tlan.txt for details */ static int debug; +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "ThunderLAN debug mask"); static int bbuf; +module_param(bbuf, int, 0); +MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)"); + static u8 *TLanPadBuffer; static dma_addr_t TLanPadBufferDMA; static char TLanSignature[] = "TLAN"; -- cgit v1.2.2 From 4b40033ef110b833986c1a1d958a951b695f9fbc Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Sun, 15 May 2005 16:01:50 -0700 Subject: [SPARC]: Eliminate local MIN/MAX macros in drivers/sbus/char/aurora.c From: Christophe Lucas min/max macros from kernel.h are safe, a lot of handcrafted MIN/MAX are not. Signed-off-by: Christophe Lucas Signed-off-by: Domen Puncer --- drivers/sbus/char/aurora.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c index e5fa1703856b..650d5e924f47 100644 --- a/drivers/sbus/char/aurora.c +++ b/drivers/sbus/char/aurora.c @@ -81,10 +81,6 @@ unsigned char irqs[4] = { int irqhit=0; #endif -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - static struct tty_driver *aurora_driver; static struct Aurora_board aurora_board[AURORA_NBOARD] = { {0,}, @@ -594,7 +590,7 @@ static void aurora_transmit(struct Aurora_board const * bp, int chip) &bp->r[chip]->r[CD180_TDR]); port->COR2 &= ~COR2_ETC; } - count = MIN(port->break_length, 0xff); + count = min(port->break_length, 0xff); sbus_writeb(CD180_C_ESC, &bp->r[chip]->r[CD180_TDR]); sbus_writeb(CD180_C_DELAY, @@ -1575,7 +1571,7 @@ static int aurora_write(struct tty_struct * tty, save_flags(flags); while (1) { cli(); - c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, + c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, SERIAL_XMIT_SIZE - port->xmit_head)); if (c <= 0) { restore_flags(flags); -- cgit v1.2.2 From c16ef1ceedff27c1b452724ca7f89b729651098f Mon Sep 17 00:00:00 2001 From: Benjamin LaHaise Date: Wed, 6 Apr 2005 11:17:59 -0400 Subject: [PATCH] ns83820 update Changes: - improved DAC ifdefs from Andi Kleen - removal of dead code from Adrian Bunk - fix half duplex collision behaviour --- drivers/net/ns83820.c | 69 ++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 2fcc181a8624..c336b46bd332 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -1,4 +1,4 @@ -#define _VERSION "0.20" +#define VERSION "0.22" /* ns83820.c by Benjamin LaHaise with contributions. * * Questions/comments/discussion to linux-ns83820@kvack.org. @@ -63,9 +63,11 @@ * - fix missed txok introduced during performance * tuning * 0.20 - fix stupid RFEN thinko. i am such a smurf. - * * 20040828 0.21 - add hardware vlan accleration * by Neil Horman + * 20050406 0.22 - improved DAC ifdefs from Andi Kleen + * - removal of dead code from Adrian Bunk + * - fix half duplex collision behaviour * Driver Overview * =============== * @@ -129,18 +131,6 @@ static int lnksts = 0; /* CFG_LNKSTS bit polarity */ #undef Dprintk #define Dprintk dprintk -#if defined(CONFIG_HIGHMEM64G) || defined(__ia64__) -#define USE_64BIT_ADDR "+" -#endif - -#if defined(USE_64BIT_ADDR) -#define VERSION _VERSION USE_64BIT_ADDR -#define TRY_DAC 1 -#else -#define VERSION _VERSION -#define TRY_DAC 0 -#endif - /* tunables */ #define RX_BUF_SIZE 1500 /* 8192 */ #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) @@ -386,22 +376,16 @@ static int lnksts = 0; /* CFG_LNKSTS bit polarity */ #define LINK_DOWN 0x02 #define LINK_UP 0x04 -#ifdef USE_64BIT_ADDR -#define HW_ADDR_LEN 8 +#define HW_ADDR_LEN sizeof(dma_addr_t) #define desc_addr_set(desc, addr) \ do { \ - u64 __addr = (addr); \ - (desc)[0] = cpu_to_le32(__addr); \ - (desc)[1] = cpu_to_le32(__addr >> 32); \ + ((desc)[0] = cpu_to_le32(addr)); \ + if (HW_ADDR_LEN == 8) \ + (desc)[1] = cpu_to_le32(((u64)addr) >> 32); \ } while(0) #define desc_addr_get(desc) \ - (((u64)le32_to_cpu((desc)[1]) << 32) \ - | le32_to_cpu((desc)[0])) -#else -#define HW_ADDR_LEN 4 -#define desc_addr_set(desc, addr) ((desc)[0] = cpu_to_le32(addr)) -#define desc_addr_get(desc) (le32_to_cpu((desc)[0])) -#endif + (le32_to_cpu((desc)[0]) | \ + (HW_ADDR_LEN == 8 ? ((dma_addr_t)le32_to_cpu((desc)[1]))<<32 : 0)) #define DESC_LINK 0 #define DESC_BUFPTR (DESC_LINK + HW_ADDR_LEN/4) @@ -727,11 +711,23 @@ static void fastcall phy_intr(struct net_device *ndev) speed = ((cfg / CFG_SPDSTS0) & 3); fullduplex = (cfg & CFG_DUPSTS); - if (fullduplex) + if (fullduplex) { new_cfg |= CFG_SB; + writel(readl(dev->base + TXCFG) + | TXCFG_CSI | TXCFG_HBI, + dev->base + TXCFG); + writel(readl(dev->base + RXCFG) | RXCFG_RX_FD, + dev->base + RXCFG); + } else { + writel(readl(dev->base + TXCFG) + & ~(TXCFG_CSI | TXCFG_HBI), + dev->base + TXCFG); + writel(readl(dev->base + RXCFG) & ~(RXCFG_RX_FD), + dev->base + RXCFG); + } if ((cfg & CFG_LNKSTS) && - ((new_cfg ^ dev->CFG_cache) & CFG_MODE_1000)) { + ((new_cfg ^ dev->CFG_cache) != 0)) { writel(new_cfg, dev->base + CFG); dev->CFG_cache = new_cfg; } @@ -1189,7 +1185,6 @@ again: for (;;) { volatile u32 *desc = dev->tx_descs + (free_idx * DESC_SIZE); - u32 residue = 0; dprintk("frag[%3u]: %4u @ 0x%08Lx\n", free_idx, len, (unsigned long long)buf); @@ -1199,17 +1194,11 @@ again: desc_addr_set(desc + DESC_BUFPTR, buf); desc[DESC_EXTSTS] = cpu_to_le32(extsts); - cmdsts = ((nr_frags|residue) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0); + cmdsts = ((nr_frags) ? CMDSTS_MORE : do_intr ? CMDSTS_INTR : 0); cmdsts |= (desc == first_desc) ? 0 : CMDSTS_OWN; cmdsts |= len; desc[DESC_CMDSTS] = cpu_to_le32(cmdsts); - if (residue) { - buf += len; - len = residue; - continue; - } - if (!nr_frags) break; @@ -1841,7 +1830,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ int using_dac = 0; /* See if we can set the dma mask early on; failure is fatal. */ - if (TRY_DAC && !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) { + if (sizeof(dma_addr_t) == 8 && + !pci_set_dma_mask(pci_dev, 0xffffffffffffffffULL)) { using_dac = 1; } else if (!pci_set_dma_mask(pci_dev, 0xffffffff)) { using_dac = 0; @@ -1972,9 +1962,8 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ /* When compiled with 64 bit addressing, we must always enable * the 64 bit descriptor format. */ -#ifdef USE_64BIT_ADDR - dev->CFG_cache |= CFG_M64ADDR; -#endif + if (sizeof(dma_addr_t) == 8) + dev->CFG_cache |= CFG_M64ADDR; if (using_dac) dev->CFG_cache |= CFG_T64ADDR; -- cgit v1.2.2 From 562faf469f35bf63c0b021550811280c81bdc52e Mon Sep 17 00:00:00 2001 From: James Harper Date: Thu, 5 May 2005 15:14:18 -0700 Subject: [PATCH] fix PROMISC/bridging in TLAN driver This has been a problem for me for ages. When using bridging, the driver is switched into promiscuous mode before the link init is complete. The init complete routine then resets the promisc bit on the card so the kernel still thinks the card is in promiscuous mode but the card isn't. doh. I think this bug only shows up in bridging when the bridge is started at boot time (or something else that sets promisc at the same time the card was started). If promisc is enabled later it works. Here's a trivial (and hopefully correct) patch that works for me. It just calls the promisc/multicast setup routine after init. Cc: Jeff Garzik Signed-off-by: Andrew Morton --- drivers/net/tlan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c index f0851c424097..9680a308c62b 100644 --- a/drivers/net/tlan.c +++ b/drivers/net/tlan.c @@ -2392,6 +2392,7 @@ TLan_FinishReset( struct net_device *dev ) TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET ); return; } + TLan_SetMulticastList(dev); } /* TLan_FinishReset */ -- cgit v1.2.2 From fac9b83ea79aa3112ed245d9a4fc2a5c3ec2b7ec Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 May 2005 22:46:34 -0700 Subject: [TG3]: Add tagged status support. When supported, use the TAGGED interrupt processing support the chip provides. In this mode, instead of a "on/off" binary semaphore, an incrementing tag scheme is used to ACK interrupts. All MSI supporting chips support TAGGED mode, so the tg3_msi() interrupt handler uses it unconditionally. This invariant is verified when MSI support is tested. Since we can invoke tg3_poll() multiple times per interrupt under high packet load, we fetch a new copy of the tag value in the status block right before we actually do the work. Also, because the tagged status tells the chip exactly which work we have processed, we can make two optimizations: 1) tg3_restart_ints() need not check tg3_has_work() 2) the tg3_timer() need not poke the chip 10 times per second to keep from losing interrupt events Based upon valuable feedback from Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 195 +++++++++++++++++++++++++++++++++++++++--------------- drivers/net/tg3.h | 2 + 2 files changed, 142 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f79b02e80e75..488b8c65252d 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -420,7 +420,8 @@ static void tg3_enable_ints(struct tg3 *tp) { tw32(TG3PCI_MISC_HOST_CTRL, (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + (tp->last_tag << 24)); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); tg3_cond_int(tp); @@ -455,10 +456,16 @@ static void tg3_restart_ints(struct tg3 *tp) { tw32(TG3PCI_MISC_HOST_CTRL, (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); - tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + tp->last_tag << 24); mmiowb(); - if (tg3_has_work(tp)) + /* When doing tagged status, this work check is unnecessary. + * The last_tag we write above tells the chip which piece of + * work we've completed. + */ + if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) && + tg3_has_work(tp)) tw32(HOSTCC_MODE, tp->coalesce_mode | (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); } @@ -2862,6 +2869,9 @@ static int tg3_poll(struct net_device *netdev, int *budget) spin_lock_irqsave(&tp->lock, flags); + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + tp->last_tag = sblk->status_tag; + /* handle link change and other phy events */ if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | @@ -2928,22 +2938,21 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) spin_lock_irqsave(&tp->lock, flags); /* - * writing any value to intr-mbox-0 clears PCI INTA# and + * Writing any value to intr-mbox-0 clears PCI INTA# and * chip-internal interrupt pending events. - * writing non-zero to intr-mbox-0 additional tells the + * Writing non-zero to intr-mbox-0 additional tells the * NIC to stop sending us irqs, engaging "in-intr-handler" * event coalescing. */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + tp->last_tag = sblk->status_tag; sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) netif_rx_schedule(dev); /* schedule NAPI poll */ else { - /* no work, re-enable interrupts - */ + /* No work, re-enable interrupts. */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000000); + tp->last_tag << 24); } spin_unlock_irqrestore(&tp->lock, flags); @@ -2969,21 +2978,62 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((sblk->status & SD_STATUS_UPDATED) || !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { /* - * writing any value to intr-mbox-0 clears PCI INTA# and + * Writing any value to intr-mbox-0 clears PCI INTA# and * chip-internal interrupt pending events. - * writing non-zero to intr-mbox-0 additional tells the + * Writing non-zero to intr-mbox-0 additional tells the * NIC to stop sending us irqs, engaging "in-intr-handler" * event coalescing. */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); + sblk->status &= ~SD_STATUS_UPDATED; + if (likely(tg3_has_work(tp))) + netif_rx_schedule(dev); /* schedule NAPI poll */ + else { + /* No work, shared interrupt perhaps? re-enable + * interrupts, and flush that PCI write + */ + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000000); + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + } + } else { /* shared interrupt */ + handled = 0; + } + + spin_unlock_irqrestore(&tp->lock, flags); + + return IRQ_RETVAL(handled); +} + +static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs) +{ + struct net_device *dev = dev_id; + struct tg3 *tp = netdev_priv(dev); + struct tg3_hw_status *sblk = tp->hw_status; + unsigned long flags; + unsigned int handled = 1; + + spin_lock_irqsave(&tp->lock, flags); + + /* In INTx mode, it is possible for the interrupt to arrive at + * the CPU before the status block posted prior to the interrupt. + * Reading the PCI State register will confirm whether the + * interrupt is ours and will flush the status block. + */ + if ((sblk->status & SD_STATUS_UPDATED) || + !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { /* - * Flush PCI write. This also guarantees that our - * status block has been flushed to host memory. + * writing any value to intr-mbox-0 clears PCI INTA# and + * chip-internal interrupt pending events. + * writing non-zero to intr-mbox-0 additional tells the + * NIC to stop sending us irqs, engaging "in-intr-handler" + * event coalescing. */ - tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, + 0x00000001); + tp->last_tag = sblk->status_tag; sblk->status &= ~SD_STATUS_UPDATED; - if (likely(tg3_has_work(tp))) netif_rx_schedule(dev); /* schedule NAPI poll */ else { @@ -2991,7 +3041,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) * interrupts, and flush that PCI write */ tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, - 0x00000000); + tp->last_tag << 24); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); } } else { /* shared interrupt */ @@ -5445,7 +5495,8 @@ static int tg3_reset_hw(struct tg3 *tp) udelay(100); tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); - tr32(MAILBOX_INTERRUPT_0); + tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); + tp->last_tag = 0; if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); @@ -5723,31 +5774,33 @@ static void tg3_timer(unsigned long __opaque) spin_lock_irqsave(&tp->lock, flags); spin_lock(&tp->tx_lock); - /* All of this garbage is because when using non-tagged - * IRQ status the mailbox/status_block protocol the chip - * uses with the cpu is race prone. - */ - if (tp->hw_status->status & SD_STATUS_UPDATED) { - tw32(GRC_LOCAL_CTRL, - tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); - } else { - tw32(HOSTCC_MODE, tp->coalesce_mode | - (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); - } + if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { + /* All of this garbage is because when using non-tagged + * IRQ status the mailbox/status_block protocol the chip + * uses with the cpu is race prone. + */ + if (tp->hw_status->status & SD_STATUS_UPDATED) { + tw32(GRC_LOCAL_CTRL, + tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); + } else { + tw32(HOSTCC_MODE, tp->coalesce_mode | + (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); + } - if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { - tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; - spin_unlock(&tp->tx_lock); - spin_unlock_irqrestore(&tp->lock, flags); - schedule_work(&tp->reset_task); - return; + if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { + tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; + spin_unlock(&tp->tx_lock); + spin_unlock_irqrestore(&tp->lock, flags); + schedule_work(&tp->reset_task); + return; + } } - if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) - tg3_periodic_fetch_stats(tp); - /* This part only runs once per second. */ if (!--tp->timer_counter) { + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + tg3_periodic_fetch_stats(tp); + if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { u32 mac_stat; int phy_event; @@ -5846,9 +5899,13 @@ static int tg3_test_interrupt(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) err = request_irq(tp->pdev->irq, tg3_msi, SA_SAMPLE_RANDOM, dev->name, dev); - else - err = request_irq(tp->pdev->irq, tg3_interrupt, + else { + irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + fn = tg3_interrupt_tagged; + err = request_irq(tp->pdev->irq, fn, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + } if (err) return err; @@ -5900,9 +5957,14 @@ static int tg3_test_msi(struct tg3 *tp) tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; - err = request_irq(tp->pdev->irq, tg3_interrupt, - SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + { + irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + fn = tg3_interrupt_tagged; + err = request_irq(tp->pdev->irq, fn, + SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + } if (err) return err; @@ -5948,7 +6010,13 @@ static int tg3_open(struct net_device *dev) if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) { - if (pci_enable_msi(tp->pdev) == 0) { + /* All MSI supporting chips should support tagged + * status. Assert that this is the case. + */ + if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { + printk(KERN_WARNING PFX "%s: MSI without TAGGED? " + "Not using MSI.\n", tp->dev->name); + } else if (pci_enable_msi(tp->pdev) == 0) { u32 msi_mode; msi_mode = tr32(MSGINT_MODE); @@ -5959,9 +6027,14 @@ static int tg3_open(struct net_device *dev) if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) err = request_irq(tp->pdev->irq, tg3_msi, SA_SAMPLE_RANDOM, dev->name, dev); - else - err = request_irq(tp->pdev->irq, tg3_interrupt, + else { + irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + fn = tg3_interrupt_tagged; + + err = request_irq(tp->pdev->irq, fn, SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + } if (err) { if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { @@ -5980,9 +6053,16 @@ static int tg3_open(struct net_device *dev) tg3_halt(tp, 1); tg3_free_rings(tp); } else { - tp->timer_offset = HZ / 10; - tp->timer_counter = tp->timer_multiplier = 10; - tp->asf_counter = tp->asf_multiplier = (10 * 120); + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + tp->timer_offset = HZ; + else + tp->timer_offset = HZ / 10; + + BUG_ON(tp->timer_offset > HZ); + tp->timer_counter = tp->timer_multiplier = + (HZ / tp->timer_offset); + tp->asf_counter = tp->asf_multiplier = + ((HZ / tp->timer_offset) * 120); init_timer(&tp->timer); tp->timer.expires = jiffies + tp->timer_offset; @@ -6005,6 +6085,7 @@ static int tg3_open(struct net_device *dev) if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { err = tg3_test_msi(tp); + if (err) { spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); @@ -8422,15 +8503,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; - /* Only 5701 and later support tagged irq status mode. - * Also, 5788 chips cannot use tagged irq status. - * - * However, since we are using NAPI avoid tagged irq status - * because the interrupt condition is more difficult to - * fully clear in that mode. - */ tp->coalesce_mode = 0; - if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) tp->coalesce_mode |= HOSTCC_MODE_32BYTE; @@ -8494,6 +8567,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) tp->tg3_flags2 |= TG3_FLG2_IS_5788; + if (!(tp->tg3_flags2 & TG3_FLG2_IS_5788) && + (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)) + tp->tg3_flags |= TG3_FLAG_TAGGED_STATUS; + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { + tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD | + HOSTCC_MODE_CLRTICK_TXBD); + + tp->misc_host_ctrl |= MISC_HOST_CTRL_TAGGED_STATUS; + pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, + tp->misc_host_ctrl); + } + /* these are limited to 10/100 only */ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 8de6f21037ba..44c65160a20f 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2023,6 +2023,7 @@ struct tg3 { struct tg3_hw_status *hw_status; dma_addr_t status_mapping; + u32 last_tag; u32 msg_enable; @@ -2068,6 +2069,7 @@ struct tg3 { u32 rx_offset; u32 tg3_flags; +#define TG3_FLAG_TAGGED_STATUS 0x00000001 #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 #define TG3_FLAG_RX_CHECKSUMS 0x00000004 #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 -- cgit v1.2.2 From 15f9850d3c2d46f5851a424d2990a18b5bb5ebfd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 May 2005 22:49:26 -0700 Subject: [TG3]: Set minimal hw interrupt mitigation. Even though we do software interrupt mitigation via NAPI, it still helps to have some minimal hw assisted mitigation. This helps, particularly, on systems where register I/O overhead is much greater than the CPU horsepower. For example, it helps on NUMA systems. In such cases the PIO overhead to disable interrupts for NAPI accounts for the majority of the packet processing cost. The CPU is fast enough such that only a single packet is processed by each NAPI poll call. Thanks to Michael Chan for reviewing this patch. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 72 +++++++++++++++++++++++++++++++++++++++++++++---------- drivers/net/tg3.h | 6 ++++- 2 files changed, 64 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 488b8c65252d..3df5b78d2693 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2507,7 +2507,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { if (netif_carrier_ok(tp->dev)) { tw32(HOSTCC_STAT_COAL_TICKS, - DEFAULT_STAT_COAL_TICKS); + tp->coal.stats_block_coalesce_usecs); } else { tw32(HOSTCC_STAT_COAL_TICKS, 0); } @@ -5094,6 +5094,27 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr, } static void __tg3_set_rx_mode(struct net_device *); +static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) +{ + tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs); + tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs); + tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames); + tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames); + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { + tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq); + tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq); + } + tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq); + tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq); + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { + u32 val = ec->stats_block_coalesce_usecs; + + if (!netif_carrier_ok(tp->dev)) + val = 0; + + tw32(HOSTCC_STAT_COAL_TICKS, val); + } +} /* tp->lock is held. */ static int tg3_reset_hw(struct tg3 *tp) @@ -5416,16 +5437,7 @@ static int tg3_reset_hw(struct tg3 *tp) udelay(10); } - tw32(HOSTCC_RXCOL_TICKS, 0); - tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS); - tw32(HOSTCC_RXMAX_FRAMES, 1); - tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES); - if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { - tw32(HOSTCC_RXCOAL_TICK_INT, 0); - tw32(HOSTCC_TXCOAL_TICK_INT, 0); - } - tw32(HOSTCC_RXCOAL_MAXF_INT, 1); - tw32(HOSTCC_TXCOAL_MAXF_INT, 0); + tg3_set_coalesce(tp, &tp->coal); /* set status block DMA address */ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, @@ -5438,8 +5450,6 @@ static int tg3_reset_hw(struct tg3 *tp) * the tg3_periodic_fetch_stats call there, and * tg3_get_stats to see how this works for 5705/5750 chips. */ - tw32(HOSTCC_STAT_COAL_TICKS, - DEFAULT_STAT_COAL_TICKS); tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, ((u64) tp->stats_mapping >> 32)); tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, @@ -7284,6 +7294,14 @@ static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) } #endif +static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) +{ + struct tg3 *tp = netdev_priv(dev); + + memcpy(ec, &tp->coal, sizeof(*ec)); + return 0; +} + static struct ethtool_ops tg3_ethtool_ops = { .get_settings = tg3_get_settings, .set_settings = tg3_set_settings, @@ -7316,6 +7334,7 @@ static struct ethtool_ops tg3_ethtool_ops = { .get_strings = tg3_get_strings, .get_stats_count = tg3_get_stats_count, .get_ethtool_stats = tg3_get_ethtool_stats, + .get_coalesce = tg3_get_coalesce, }; static void __devinit tg3_get_eeprom_size(struct tg3 *tp) @@ -9096,6 +9115,31 @@ static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) return peer; } +static void __devinit tg3_init_coal(struct tg3 *tp) +{ + struct ethtool_coalesce *ec = &tp->coal; + + memset(ec, 0, sizeof(*ec)); + ec->cmd = ETHTOOL_GCOALESCE; + ec->rx_coalesce_usecs = LOW_RXCOL_TICKS; + ec->tx_coalesce_usecs = LOW_TXCOL_TICKS; + ec->rx_max_coalesced_frames = LOW_RXMAX_FRAMES; + ec->tx_max_coalesced_frames = LOW_TXMAX_FRAMES; + ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT; + ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT; + ec->rx_max_coalesced_frames_irq = DEFAULT_RXCOAL_MAXF_INT; + ec->tx_max_coalesced_frames_irq = DEFAULT_TXCOAL_MAXF_INT; + ec->stats_block_coalesce_usecs = DEFAULT_STAT_COAL_TICKS; + + if (tp->coalesce_mode & (HOSTCC_MODE_CLRTICK_RXBD | + HOSTCC_MODE_CLRTICK_TXBD)) { + ec->rx_coalesce_usecs = LOW_RXCOL_TICKS_CLRTCKS; + ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT_CLRTCKS; + ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS; + ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS; + } +} + static int __devinit tg3_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -9341,6 +9385,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, /* flow control autonegotiation is default behavior */ tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; + tg3_init_coal(tp); + err = register_netdev(dev); if (err) { printk(KERN_ERR PFX "Cannot register net device, " diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 44c65160a20f..993f84c93dc4 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -876,10 +876,12 @@ #define HOSTCC_STATUS_ERROR_ATTN 0x00000004 #define HOSTCC_RXCOL_TICKS 0x00003c08 #define LOW_RXCOL_TICKS 0x00000032 +#define LOW_RXCOL_TICKS_CLRTCKS 0x00000014 #define DEFAULT_RXCOL_TICKS 0x00000048 #define HIGH_RXCOL_TICKS 0x00000096 #define HOSTCC_TXCOL_TICKS 0x00003c0c #define LOW_TXCOL_TICKS 0x00000096 +#define LOW_TXCOL_TICKS_CLRTCKS 0x00000048 #define DEFAULT_TXCOL_TICKS 0x0000012c #define HIGH_TXCOL_TICKS 0x00000145 #define HOSTCC_RXMAX_FRAMES 0x00003c10 @@ -892,8 +894,10 @@ #define HIGH_TXMAX_FRAMES 0x00000052 #define HOSTCC_RXCOAL_TICK_INT 0x00003c18 #define DEFAULT_RXCOAL_TICK_INT 0x00000019 +#define DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014 #define HOSTCC_TXCOAL_TICK_INT 0x00003c1c #define DEFAULT_TXCOAL_TICK_INT 0x00000019 +#define DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014 #define HOSTCC_RXCOAL_MAXF_INT 0x00003c20 #define DEFAULT_RXCOAL_MAXF_INT 0x00000005 #define HOSTCC_TXCOAL_MAXF_INT 0x00003c24 @@ -2227,7 +2231,7 @@ struct tg3 { #define SST_25VF0X0_PAGE_SIZE 4098 - + struct ethtool_coalesce coal; }; #endif /* !(_T3_H) */ -- cgit v1.2.2 From 59e6b4343299373bc10dd131ab5142f53ddd838a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 May 2005 22:50:10 -0700 Subject: [TG3]: Refine DMA boundary setting. Extract DMA boundary bit selection into a seperate function, tg3_calc_dma_bndry(). Call this from tg3_test_dma(). Make DMA test more reliable by using no DMA boundry setting during the test. If the test passes, then use the setting we selected before the test. Signed-off-by: David S. Miller Signed-off-by: Michael Chan --- drivers/net/tg3.c | 207 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 163 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 3df5b78d2693..4ab9680ffbd2 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8775,6 +8775,146 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) return 0; } +#define BOUNDARY_SINGLE_CACHELINE 1 +#define BOUNDARY_MULTI_CACHELINE 2 + +static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val) +{ + int cacheline_size; + u8 byte; + int goal; + + pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + /* On 5703 and later chips, the boundary bits have no + * effect. + */ + if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && + GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 && + !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) + goto out; + +#if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC) + goal = BOUNDARY_MULTI_CACHELINE; +#else +#if defined(CONFIG_SPARC64) || defined(CONFIG_ALPHA) + goal = BOUNDARY_SINGLE_CACHELINE; +#else + goal = 0; +#endif +#endif + + if (!goal) + goto out; + + /* PCI controllers on most RISC systems tend to disconnect + * when a device tries to burst across a cache-line boundary. + * Therefore, letting tg3 do so just wastes PCI bandwidth. + * + * Unfortunately, for PCI-E there are only limited + * write-side controls for this, and thus for reads + * we will still get the disconnects. We'll also waste + * these PCI cycles for both read and write for chips + * other than 5700 and 5701 which do not implement the + * boundary bits. + */ + if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && + !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) { + switch (cacheline_size) { + case 16: + case 32: + case 64: + case 128: + if (goal == BOUNDARY_SINGLE_CACHELINE) { + val |= (DMA_RWCTRL_READ_BNDRY_128_PCIX | + DMA_RWCTRL_WRITE_BNDRY_128_PCIX); + } else { + val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX | + DMA_RWCTRL_WRITE_BNDRY_384_PCIX); + } + break; + + case 256: + val |= (DMA_RWCTRL_READ_BNDRY_256_PCIX | + DMA_RWCTRL_WRITE_BNDRY_256_PCIX); + break; + + default: + val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX | + DMA_RWCTRL_WRITE_BNDRY_384_PCIX); + break; + }; + } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { + switch (cacheline_size) { + case 16: + case 32: + case 64: + if (goal == BOUNDARY_SINGLE_CACHELINE) { + val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE; + val |= DMA_RWCTRL_WRITE_BNDRY_64_PCIE; + break; + } + /* fallthrough */ + case 128: + default: + val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE; + val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE; + break; + }; + } else { + switch (cacheline_size) { + case 16: + if (goal == BOUNDARY_SINGLE_CACHELINE) { + val |= (DMA_RWCTRL_READ_BNDRY_16 | + DMA_RWCTRL_WRITE_BNDRY_16); + break; + } + /* fallthrough */ + case 32: + if (goal == BOUNDARY_SINGLE_CACHELINE) { + val |= (DMA_RWCTRL_READ_BNDRY_32 | + DMA_RWCTRL_WRITE_BNDRY_32); + break; + } + /* fallthrough */ + case 64: + if (goal == BOUNDARY_SINGLE_CACHELINE) { + val |= (DMA_RWCTRL_READ_BNDRY_64 | + DMA_RWCTRL_WRITE_BNDRY_64); + break; + } + /* fallthrough */ + case 128: + if (goal == BOUNDARY_SINGLE_CACHELINE) { + val |= (DMA_RWCTRL_READ_BNDRY_128 | + DMA_RWCTRL_WRITE_BNDRY_128); + break; + } + /* fallthrough */ + case 256: + val |= (DMA_RWCTRL_READ_BNDRY_256 | + DMA_RWCTRL_WRITE_BNDRY_256); + break; + case 512: + val |= (DMA_RWCTRL_READ_BNDRY_512 | + DMA_RWCTRL_WRITE_BNDRY_512); + break; + case 1024: + default: + val |= (DMA_RWCTRL_READ_BNDRY_1024 | + DMA_RWCTRL_WRITE_BNDRY_1024); + break; + }; + } + +out: + return val; +} + static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dma, int size, int to_device) { struct tg3_internal_buffer_desc test_desc; @@ -8861,7 +9001,7 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm static int __devinit tg3_test_dma(struct tg3 *tp) { dma_addr_t buf_dma; - u32 *buf; + u32 *buf, saved_dma_rwctrl; int ret; buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma); @@ -8873,46 +9013,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) tp->dma_rwctrl = ((0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) | (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT)); -#ifndef CONFIG_X86 - { - u8 byte; - int cacheline_size; - pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte); - - if (byte == 0) - cacheline_size = 1024; - else - cacheline_size = (int) byte * 4; - - switch (cacheline_size) { - case 16: - case 32: - case 64: - case 128: - if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && - !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) { - tp->dma_rwctrl |= - DMA_RWCTRL_WRITE_BNDRY_384_PCIX; - break; - } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { - tp->dma_rwctrl &= - ~(DMA_RWCTRL_PCI_WRITE_CMD); - tp->dma_rwctrl |= - DMA_RWCTRL_WRITE_BNDRY_128_PCIE; - break; - } - /* fallthrough */ - case 256: - if (!(tp->tg3_flags & TG3_FLAG_PCIX_MODE) && - !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) - tp->dma_rwctrl |= - DMA_RWCTRL_WRITE_BNDRY_256; - else if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) - tp->dma_rwctrl |= - DMA_RWCTRL_WRITE_BNDRY_256_PCIX; - }; - } -#endif + tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl); if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { /* DMA read watermark not used on PCIE */ @@ -8931,7 +9032,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) if (ccval == 0x6 || ccval == 0x7) tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; - /* Set bit 23 to renable PCIX hw bug fix */ + /* Set bit 23 to enable PCIX hw bug fix */ tp->dma_rwctrl |= 0x009f0000; } else { tp->dma_rwctrl |= 0x001b000f; @@ -8972,6 +9073,13 @@ static int __devinit tg3_test_dma(struct tg3 *tp) GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) goto out; + /* It is best to perform DMA test with maximum write burst size + * to expose the 5700/5701 write DMA bug. + */ + saved_dma_rwctrl = tp->dma_rwctrl; + tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); + while (1) { u32 *p = buf, i; @@ -9010,8 +9118,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp) if (p[i] == i) continue; - if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) == - DMA_RWCTRL_WRITE_BNDRY_DISAB) { + if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != + DMA_RWCTRL_WRITE_BNDRY_16) { + tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); break; @@ -9028,6 +9137,14 @@ static int __devinit tg3_test_dma(struct tg3 *tp) break; } } + if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != + DMA_RWCTRL_WRITE_BNDRY_16) { + /* DMA test passed without adjusting DMA boundary, + * just restore the calculated DMA boundary + */ + tp->dma_rwctrl = saved_dma_rwctrl; + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); + } out: pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma); @@ -9429,6 +9546,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); + printk(KERN_INFO "%s: dma_rwctrl[%08x]\n", + dev->name, tp->dma_rwctrl); return 0; -- cgit v1.2.2 From f7383c22246cfccbe912541dd83103009ed2b537 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 18 May 2005 22:50:53 -0700 Subject: [TG3]: In tg3_poll(), resample status_tag after doing work. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4ab9680ffbd2..4d2bdbdd34e8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -2869,9 +2869,6 @@ static int tg3_poll(struct net_device *netdev, int *budget) spin_lock_irqsave(&tp->lock, flags); - if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) - tp->last_tag = sblk->status_tag; - /* handle link change and other phy events */ if (!(tp->tg3_flags & (TG3_FLAG_USE_LINKCHG_REG | @@ -2896,7 +2893,6 @@ static int tg3_poll(struct net_device *netdev, int *budget) * All RX "locking" is done by ensuring outside * code synchronizes with dev->poll() */ - done = 1; if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { int orig_budget = *budget; int work_done; @@ -2908,12 +2904,14 @@ static int tg3_poll(struct net_device *netdev, int *budget) *budget -= work_done; netdev->quota -= work_done; - - if (work_done >= orig_budget) - done = 0; } + if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) + tp->last_tag = sblk->status_tag; + rmb(); + /* if no more work, tell net stack and NIC we're done */ + done = !tg3_has_work(tp); if (done) { spin_lock_irqsave(&tp->lock, flags); __netif_rx_complete(netdev); -- cgit v1.2.2 From 37e0915b701281182cea9fc90e894d10addf134a Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Fri, 20 May 2005 08:56:23 +0200 Subject: [PATCH] Add sysfs support for the IPMI device interface Add support for sysfs to the IPMI device interface. Clean-ups based on Dimitry Torokovs comment by Philipp Hahn. Signed-off-by: Corey Minyard Signed-off-by: Philipp Hahn Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_devintf.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 49d67f5384a2..4bb9af736fba 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -44,6 +44,7 @@ #include #include #include +#include #define IPMI_DEVINTF_VERSION "v33" @@ -519,15 +520,21 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By" " interface. Other values will set the major device number" " to that value."); +static struct class *ipmi_class; + static void ipmi_new_smi(int if_num) { - devfs_mk_cdev(MKDEV(ipmi_major, if_num), - S_IFCHR | S_IRUSR | S_IWUSR, + dev_t dev = MKDEV(ipmi_major, if_num); + + devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, "ipmidev/%d", if_num); + + class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num); } static void ipmi_smi_gone(int if_num) { + class_simple_device_remove(ipmi_class, MKDEV(ipmi_major, if_num)); devfs_remove("ipmidev/%d", if_num); } @@ -548,8 +555,15 @@ static __init int init_ipmi_devintf(void) printk(KERN_INFO "ipmi device interface version " IPMI_DEVINTF_VERSION "\n"); + ipmi_class = class_simple_create(THIS_MODULE, "ipmi"); + if (IS_ERR(ipmi_class)) { + printk(KERN_ERR "ipmi: can't register device class\n"); + return PTR_ERR(ipmi_class); + } + rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops); if (rv < 0) { + class_simple_destroy(ipmi_class); printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major); return rv; } @@ -563,6 +577,7 @@ static __init int init_ipmi_devintf(void) rv = ipmi_smi_watcher_register(&smi_watcher); if (rv) { unregister_chrdev(ipmi_major, DEVICE_NAME); + class_simple_destroy(ipmi_class); printk(KERN_WARNING "ipmi: can't register smi watcher\n"); return rv; } @@ -573,6 +588,7 @@ module_init(init_ipmi_devintf); static __exit void cleanup_ipmi(void) { + class_simple_destroy(ipmi_class); ipmi_smi_watcher_unregister(&smi_watcher); devfs_remove(DEVICE_NAME); unregister_chrdev(ipmi_major, DEVICE_NAME); -- cgit v1.2.2 From 62a8612972eaea804e1e42c63ee403cd4e14cc35 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 6 May 2005 18:05:20 -0500 Subject: [SCSI] implement parameter limits in the SPI transport class There's a basic need not to have parameters go under or over certain values when doing domain validation. The basic ones are max_offset, max_width and min_period This patch makes the transport class take and enforce these three limits. Currently they can be set by the user, although they could obviously be read from the HBA's on-board NVRAM area during slave_configure (if it has one). Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_spi.c | 188 ++++++++++++++++++++++++++++++++------ 1 file changed, 161 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 28966d05435c..67c6cc40ce16 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -35,7 +35,7 @@ #define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a) -#define SPI_NUM_ATTRS 10 /* increase this if you add attributes */ +#define SPI_NUM_ATTRS 13 /* increase this if you add attributes */ #define SPI_OTHER_ATTRS 1 /* Increase this if you add "always * on" attributes */ #define SPI_HOST_ATTRS 1 @@ -219,8 +219,11 @@ static int spi_setup_transport_attrs(struct device *dev) struct scsi_target *starget = to_scsi_target(dev); spi_period(starget) = -1; /* illegal value */ + spi_min_period(starget) = 0; spi_offset(starget) = 0; /* async */ + spi_max_offset(starget) = 255; spi_width(starget) = 0; /* narrow */ + spi_max_width(starget) = 1; spi_iu(starget) = 0; /* no IU */ spi_dt(starget) = 0; /* ST */ spi_qas(starget) = 0; @@ -235,6 +238,34 @@ static int spi_setup_transport_attrs(struct device *dev) return 0; } +#define spi_transport_show_simple(field, format_string) \ + \ +static ssize_t \ +show_spi_transport_##field(struct class_device *cdev, char *buf) \ +{ \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct spi_transport_attrs *tp; \ + \ + tp = (struct spi_transport_attrs *)&starget->starget_data; \ + return snprintf(buf, 20, format_string, tp->field); \ +} + +#define spi_transport_store_simple(field, format_string) \ + \ +static ssize_t \ +store_spi_transport_##field(struct class_device *cdev, const char *buf, \ + size_t count) \ +{ \ + int val; \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct spi_transport_attrs *tp; \ + \ + tp = (struct spi_transport_attrs *)&starget->starget_data; \ + val = simple_strtoul(buf, NULL, 0); \ + tp->field = val; \ + return count; \ +} + #define spi_transport_show_function(field, format_string) \ \ static ssize_t \ @@ -261,6 +292,25 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \ struct spi_internal *i = to_spi_internal(shost->transportt); \ \ val = simple_strtoul(buf, NULL, 0); \ + i->f->set_##field(starget, val); \ + return count; \ +} + +#define spi_transport_store_max(field, format_string) \ +static ssize_t \ +store_spi_transport_##field(struct class_device *cdev, const char *buf, \ + size_t count) \ +{ \ + int val; \ + struct scsi_target *starget = transport_class_to_starget(cdev); \ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ + struct spi_internal *i = to_spi_internal(shost->transportt); \ + struct spi_transport_attrs *tp \ + = (struct spi_transport_attrs *)&starget->starget_data; \ + \ + val = simple_strtoul(buf, NULL, 0); \ + if (val > tp->max_##field) \ + val = tp->max_##field; \ i->f->set_##field(starget, val); \ return count; \ } @@ -272,9 +322,24 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ show_spi_transport_##field, \ store_spi_transport_##field); +#define spi_transport_simple_attr(field, format_string) \ + spi_transport_show_simple(field, format_string) \ + spi_transport_store_simple(field, format_string) \ +static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ + show_spi_transport_##field, \ + store_spi_transport_##field); + +#define spi_transport_max_attr(field, format_string) \ + spi_transport_show_function(field, format_string) \ + spi_transport_store_max(field, format_string) \ + spi_transport_simple_attr(max_##field, format_string) \ +static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ + show_spi_transport_##field, \ + store_spi_transport_##field); + /* The Parallel SCSI Tranport Attributes: */ -spi_transport_rd_attr(offset, "%d\n"); -spi_transport_rd_attr(width, "%d\n"); +spi_transport_max_attr(offset, "%d\n"); +spi_transport_max_attr(width, "%d\n"); spi_transport_rd_attr(iu, "%d\n"); spi_transport_rd_attr(dt, "%d\n"); spi_transport_rd_attr(qas, "%d\n"); @@ -300,26 +365,18 @@ static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate); /* Translate the period into ns according to the current spec * for SDTR/PPR messages */ -static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) - +static ssize_t +show_spi_transport_period_helper(struct class_device *cdev, char *buf, + int period) { - struct scsi_target *starget = transport_class_to_starget(cdev); - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct spi_transport_attrs *tp; int len, picosec; - struct spi_internal *i = to_spi_internal(shost->transportt); - - tp = (struct spi_transport_attrs *)&starget->starget_data; - - if (i->f->get_period) - i->f->get_period(starget); - if (tp->period < 0 || tp->period > 0xff) { + if (period < 0 || period > 0xff) { picosec = -1; - } else if (tp->period <= SPI_STATIC_PPR) { - picosec = ppr_to_ps[tp->period]; + } else if (period <= SPI_STATIC_PPR) { + picosec = ppr_to_ps[period]; } else { - picosec = tp->period * 4000; + picosec = period * 4000; } if (picosec == -1) { @@ -334,12 +391,9 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) } static ssize_t -store_spi_transport_period(struct class_device *cdev, const char *buf, - size_t count) +store_spi_transport_period_helper(struct class_device *cdev, const char *buf, + size_t count, int *periodp) { - struct scsi_target *starget = transport_class_to_starget(cdev); - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct spi_internal *i = to_spi_internal(shost->transportt); int j, picosec, period = -1; char *endp; @@ -368,15 +422,79 @@ store_spi_transport_period(struct class_device *cdev, const char *buf, if (period > 0xff) period = 0xff; - i->f->set_period(starget, period); + *periodp = period; return count; } +static ssize_t +show_spi_transport_period(struct class_device *cdev, char *buf) +{ + struct scsi_target *starget = transport_class_to_starget(cdev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct spi_internal *i = to_spi_internal(shost->transportt); + struct spi_transport_attrs *tp = + (struct spi_transport_attrs *)&starget->starget_data; + + if (i->f->get_period) + i->f->get_period(starget); + + return show_spi_transport_period_helper(cdev, buf, tp->period); +} + +static ssize_t +store_spi_transport_period(struct class_device *cdev, const char *buf, + size_t count) +{ + struct scsi_target *starget = transport_class_to_starget(cdev); + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct spi_internal *i = to_spi_internal(shost->transportt); + struct spi_transport_attrs *tp = + (struct spi_transport_attrs *)&starget->starget_data; + int period, retval; + + retval = store_spi_transport_period_helper(cdev, buf, count, &period); + + if (period < tp->min_period) + period = tp->min_period; + + i->f->set_period(starget, period); + + return retval; +} + static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR, show_spi_transport_period, store_spi_transport_period); +static ssize_t +show_spi_transport_min_period(struct class_device *cdev, char *buf) +{ + struct scsi_target *starget = transport_class_to_starget(cdev); + struct spi_transport_attrs *tp = + (struct spi_transport_attrs *)&starget->starget_data; + + return show_spi_transport_period_helper(cdev, buf, tp->min_period); +} + +static ssize_t +store_spi_transport_min_period(struct class_device *cdev, const char *buf, + size_t count) +{ + struct scsi_target *starget = transport_class_to_starget(cdev); + struct spi_transport_attrs *tp = + (struct spi_transport_attrs *)&starget->starget_data; + + return store_spi_transport_period_helper(cdev, buf, count, + &tp->min_period); +} + + +static CLASS_DEVICE_ATTR(min_period, S_IRUGO | S_IWUSR, + show_spi_transport_min_period, + store_spi_transport_min_period); + + static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf) { struct Scsi_Host *shost = transport_class_to_shost(cdev); @@ -642,6 +760,7 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) { struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); struct scsi_device *sdev = sreq->sr_device; + struct scsi_target *starget = sdev->sdev_target; int len = sdev->inquiry_len; /* first set us up for narrow async */ DV_SET(offset, 0); @@ -655,9 +774,11 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) } /* test width */ - if (i->f->set_width && sdev->wdtr) { + if (i->f->set_width && spi_max_width(starget) && sdev->wdtr) { i->f->set_width(sdev->sdev_target, 1); + printk("WIDTH IS %d\n", spi_max_width(starget)); + if (spi_dv_device_compare_inquiry(sreq, buffer, buffer + len, DV_LOOPS) @@ -684,8 +805,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) retry: /* now set up to the maximum */ - DV_SET(offset, 255); - DV_SET(period, 1); + DV_SET(offset, spi_max_offset(starget)); + DV_SET(period, spi_min_period(starget)); if (len == 0) { SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n"); @@ -892,6 +1013,16 @@ EXPORT_SYMBOL(spi_display_xfer_agreement); if (i->f->show_##field) \ count++ +#define SETUP_RELATED_ATTRIBUTE(field, rel_field) \ + i->private_attrs[count] = class_device_attr_##field; \ + if (!i->f->set_##rel_field) { \ + i->private_attrs[count].attr.mode = S_IRUGO; \ + i->private_attrs[count].store = NULL; \ + } \ + i->attrs[count] = &i->private_attrs[count]; \ + if (i->f->show_##rel_field) \ + count++ + #define SETUP_HOST_ATTRIBUTE(field) \ i->private_host_attrs[count] = class_device_attr_##field; \ if (!i->f->set_##field) { \ @@ -975,8 +1106,11 @@ spi_attach_transport(struct spi_function_template *ft) i->f = ft; SETUP_ATTRIBUTE(period); + SETUP_RELATED_ATTRIBUTE(min_period, period); SETUP_ATTRIBUTE(offset); + SETUP_RELATED_ATTRIBUTE(max_offset, offset); SETUP_ATTRIBUTE(width); + SETUP_RELATED_ATTRIBUTE(max_width, width); SETUP_ATTRIBUTE(iu); SETUP_ATTRIBUTE(dt); SETUP_ATTRIBUTE(qas); -- cgit v1.2.2 From fad01ef88d2a27303757924c1fc013b31fe9a76b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 8 May 2005 16:00:15 -0500 Subject: [SCSI] correct aic7xxx period setting routines This is similar to the previous sym2 problem. For Domain Validation to work we can't allow any period setting to turn wide on if it was previously off. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 71 ++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index d978e4a3e973..0ed9ccc3091e 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -3346,6 +3346,32 @@ ahc_platform_dump_card_state(struct ahc_softc *ahc) static void ahc_linux_exit(void); +static void ahc_linux_get_width(struct scsi_target *starget) +{ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); + struct ahc_tmode_tstate *tstate; + struct ahc_initiator_tinfo *tinfo + = ahc_fetch_transinfo(ahc, + starget->channel + 'A', + shost->this_id, starget->id, &tstate); + spi_width(starget) = tinfo->curr.width; +} + +static void ahc_linux_set_width(struct scsi_target *starget, int width) +{ + struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); + struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); + struct ahc_devinfo devinfo; + unsigned long flags; + + ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, + starget->channel + 'A', ROLE_INITIATOR); + ahc_lock(ahc, &flags); + ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE); + ahc_unlock(ahc, &flags); +} + static void ahc_linux_get_period(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -3378,6 +3404,14 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); + + /* all PPR requests apart from QAS require wide transfers */ + if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) { + ahc_linux_get_width(starget); + if (spi_width(starget) == 0) + ppr_options &= MSG_EXT_PPR_QAS_REQ; + } + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, @@ -3425,32 +3459,6 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset) ahc_unlock(ahc, &flags); } -static void ahc_linux_get_width(struct scsi_target *starget) -{ - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); - struct ahc_tmode_tstate *tstate; - struct ahc_initiator_tinfo *tinfo - = ahc_fetch_transinfo(ahc, - starget->channel + 'A', - shost->this_id, starget->id, &tstate); - spi_width(starget) = tinfo->curr.width; -} - -static void ahc_linux_set_width(struct scsi_target *starget, int width) -{ - struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); - struct ahc_devinfo devinfo; - unsigned long flags; - - ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, - starget->channel + 'A', ROLE_INITIATOR); - ahc_lock(ahc, &flags); - ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE); - ahc_unlock(ahc, &flags); -} - static void ahc_linux_get_dt(struct scsi_target *starget) { struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); @@ -3481,8 +3489,7 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, - dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, ppr_options, AHC_TRANS_GOAL, FALSE); @@ -3514,7 +3521,6 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas) unsigned int ppr_options = tinfo->curr.ppr_options & ~MSG_EXT_PPR_QAS_REQ; unsigned int period = tinfo->curr.period; - unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ; unsigned long flags; struct ahc_syncrate *syncrate; @@ -3523,8 +3529,7 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, - dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, ppr_options, AHC_TRANS_GOAL, FALSE); @@ -3556,7 +3561,6 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) unsigned int ppr_options = tinfo->curr.ppr_options & ~MSG_EXT_PPR_IU_REQ; unsigned int period = tinfo->curr.period; - unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ; unsigned long flags; struct ahc_syncrate *syncrate; @@ -3565,8 +3569,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); - syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, - dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2); + syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); ahc_lock(ahc, &flags); ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, ppr_options, AHC_TRANS_GOAL, FALSE); -- cgit v1.2.2 From e4e360c325c90f7830baaa2a27cd7a1f2bdeb6b0 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 16 May 2005 16:39:38 -0500 Subject: [SCSI] remove aic7xxx busyq The aic7xxx driver has two spurious queues in it's linux glue code: the busyq which queues incoming commands to the driver and the completeq which queues finished commands before sending them back to the mid-layer This patch just removes the busyq and makes the aic finally return the correct status to get the mid-layer to manage its queueing, so a command is either committed to the sequencer or returned to the midlayer for requeue. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 625 +++++++++++-------------------------- drivers/scsi/aic7xxx/aic7xxx_osm.h | 4 +- 2 files changed, 191 insertions(+), 438 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 0ed9ccc3091e..9017942407d8 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -458,26 +458,20 @@ static struct ahc_linux_device* ahc_linux_alloc_device(struct ahc_softc*, u_int); static void ahc_linux_free_device(struct ahc_softc*, struct ahc_linux_device*); -static void ahc_linux_run_device_queue(struct ahc_softc*, - struct ahc_linux_device*); +static int ahc_linux_run_command(struct ahc_softc*, + struct ahc_linux_device *, + struct scsi_cmnd *); static void ahc_linux_setup_tag_info_global(char *p); static aic_option_callback_t ahc_linux_setup_tag_info; static int aic7xxx_setup(char *s); static int ahc_linux_next_unit(void); -static void ahc_runq_tasklet(unsigned long data); static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc); /********************************* Inlines ************************************/ -static __inline void ahc_schedule_runq(struct ahc_softc *ahc); static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, u_int lun, int alloc); static __inline void ahc_schedule_completeq(struct ahc_softc *ahc); -static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc, - struct ahc_linux_device *dev); -static __inline struct ahc_linux_device * - ahc_linux_next_device_to_run(struct ahc_softc *ahc); -static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc); static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, @@ -494,15 +488,6 @@ ahc_schedule_completeq(struct ahc_softc *ahc) } } -/* - * Must be called with our lock held. - */ -static __inline void -ahc_schedule_runq(struct ahc_softc *ahc) -{ - tasklet_schedule(&ahc->platform_data->runq_tasklet); -} - static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, u_int lun, int alloc) @@ -568,45 +553,6 @@ ahc_linux_run_complete_queue(struct ahc_softc *ahc) return (acmd); } -static __inline void -ahc_linux_check_device_queue(struct ahc_softc *ahc, - struct ahc_linux_device *dev) -{ - if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0 - && dev->active == 0) { - dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY; - dev->qfrozen--; - } - - if (TAILQ_FIRST(&dev->busyq) == NULL - || dev->openings == 0 || dev->qfrozen != 0) - return; - - ahc_linux_run_device_queue(ahc, dev); -} - -static __inline struct ahc_linux_device * -ahc_linux_next_device_to_run(struct ahc_softc *ahc) -{ - - if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0 - || (ahc->platform_data->qfrozen != 0)) - return (NULL); - return (TAILQ_FIRST(&ahc->platform_data->device_runq)); -} - -static __inline void -ahc_linux_run_device_queues(struct ahc_softc *ahc) -{ - struct ahc_linux_device *dev; - - while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { - TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); - dev->flags &= ~AHC_DEV_ON_RUN_LIST; - ahc_linux_check_device_queue(ahc, dev); - } -} - static __inline void ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) { @@ -871,7 +817,6 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) { struct ahc_softc *ahc; struct ahc_linux_device *dev; - u_long flags; ahc = *(struct ahc_softc **)cmd->device->host->hostdata; @@ -880,42 +825,22 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) */ cmd->scsi_done = scsi_done; - ahc_midlayer_entrypoint_lock(ahc, &flags); - /* * Close the race of a command that was in the process of * being queued to us just as our simq was frozen. Let * DV commands through so long as we are only frozen to * perform DV. */ - if (ahc->platform_data->qfrozen != 0) { + if (ahc->platform_data->qfrozen != 0) + return SCSI_MLQUEUE_HOST_BUSY; - ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); - ahc_linux_queue_cmd_complete(ahc, cmd); - ahc_schedule_completeq(ahc); - ahc_midlayer_entrypoint_unlock(ahc, &flags); - return (0); - } dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, cmd->device->lun, /*alloc*/TRUE); - if (dev == NULL) { - ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL); - ahc_linux_queue_cmd_complete(ahc, cmd); - ahc_schedule_completeq(ahc); - ahc_midlayer_entrypoint_unlock(ahc, &flags); - printf("%s: aic7xxx_linux_queue - Unable to allocate device!\n", - ahc_name(ahc)); - return (0); - } + BUG_ON(dev == NULL); + cmd->result = CAM_REQ_INPROG << 16; - TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); - if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; - ahc_linux_run_device_queues(ahc); - } - ahc_midlayer_entrypoint_unlock(ahc, &flags); - return (0); + + return ahc_linux_run_command(ahc, dev, cmd); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) @@ -987,8 +912,7 @@ ahc_linux_slave_destroy(Scsi_Device *device) if (dev != NULL && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) { dev->flags |= AHC_DEV_UNCONFIGURED; - if (TAILQ_EMPTY(&dev->busyq) - && dev->active == 0 + if (dev->active == 0 && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) ahc_linux_free_device(ahc, dev); } @@ -1206,33 +1130,6 @@ Scsi_Host_Template aic7xxx_driver_template = { /**************************** Tasklet Handler *********************************/ -/* - * In 2.4.X and above, this routine is called from a tasklet, - * so we must re-acquire our lock prior to executing this code. - * In all prior kernels, ahc_schedule_runq() calls this routine - * directly and ahc_schedule_runq() is called with our lock held. - */ -static void -ahc_runq_tasklet(unsigned long data) -{ - struct ahc_softc* ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = (struct ahc_softc *)data; - ahc_lock(ahc, &flags); - while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { - - TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); - dev->flags &= ~AHC_DEV_ON_RUN_LIST; - ahc_linux_check_device_queue(ahc, dev); - /* Yeild to our interrupt handler */ - ahc_unlock(ahc, &flags); - ahc_lock(ahc, &flags); - } - ahc_unlock(ahc, &flags); -} - /******************************** Macros **************************************/ #define BUILD_SCSIID(ahc, cmd) \ ((((cmd)->device->id << TID_SHIFT) & TID) \ @@ -1728,8 +1625,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) ahc->platform_data->completeq_timer.function = (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue; init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); - tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, - (unsigned long)ahc); ahc->seltime = (aic7xxx_seltime & 0x3) << 4; ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; if (aic7xxx_pci_parity == 0) @@ -1747,7 +1642,6 @@ ahc_platform_free(struct ahc_softc *ahc) if (ahc->platform_data != NULL) { del_timer_sync(&ahc->platform_data->completeq_timer); - tasklet_kill(&ahc->platform_data->runq_tasklet); if (ahc->platform_data->host != NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) scsi_remove_host(ahc->platform_data->host); @@ -1906,71 +1800,7 @@ int ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, int lun, u_int tag, role_t role, uint32_t status) { - int chan; - int maxchan; - int targ; - int maxtarg; - int clun; - int maxlun; - int count; - - if (tag != SCB_LIST_NULL) - return (0); - - chan = 0; - if (channel != ALL_CHANNELS) { - chan = channel - 'A'; - maxchan = chan + 1; - } else { - maxchan = (ahc->features & AHC_TWIN) ? 2 : 1; - } - targ = 0; - if (target != CAM_TARGET_WILDCARD) { - targ = target; - maxtarg = targ + 1; - } else { - maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8; - } - clun = 0; - if (lun != CAM_LUN_WILDCARD) { - clun = lun; - maxlun = clun + 1; - } else { - maxlun = AHC_NUM_LUNS; - } - - count = 0; - for (; chan < maxchan; chan++) { - - for (; targ < maxtarg; targ++) { - - for (; clun < maxlun; clun++) { - struct ahc_linux_device *dev; - struct ahc_busyq *busyq; - struct ahc_cmd *acmd; - - dev = ahc_linux_get_device(ahc, chan, - targ, clun, - /*alloc*/FALSE); - if (dev == NULL) - continue; - - busyq = &dev->busyq; - while ((acmd = TAILQ_FIRST(busyq)) != NULL) { - Scsi_Cmnd *cmd; - - cmd = &acmd_scsi_cmd(acmd); - TAILQ_REMOVE(busyq, acmd, - acmd_links.tqe); - count++; - cmd->result = status << 16; - ahc_linux_queue_cmd_complete(ahc, cmd); - } - } - } - } - - return (count); + return 0; } static void @@ -2045,213 +1875,203 @@ ahc_linux_device_queue_depth(struct ahc_softc *ahc, } } -static void -ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev) +static int +ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, + struct scsi_cmnd *cmd) { - struct ahc_cmd *acmd; - struct scsi_cmnd *cmd; struct scb *scb; struct hardware_scb *hscb; struct ahc_initiator_tinfo *tinfo; struct ahc_tmode_tstate *tstate; uint16_t mask; + struct scb_tailq *untagged_q = NULL; - if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0) - panic("running device on run list"); + /* + * Schedule us to run later. The only reason we are not + * running is because the whole controller Q is frozen. + */ + if (ahc->platform_data->qfrozen != 0) + return SCSI_MLQUEUE_HOST_BUSY; - while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL - && dev->openings > 0 && dev->qfrozen == 0) { + /* + * We only allow one untagged transaction + * per target in the initiator role unless + * we are storing a full busy target *lun* + * table in SCB space. + */ + if (!blk_rq_tagged(cmd->request) + && (ahc->features & AHC_SCB_BTT) == 0) { + int target_offset; - /* - * Schedule us to run later. The only reason we are not - * running is because the whole controller Q is frozen. - */ - if (ahc->platform_data->qfrozen != 0) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, - dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; - return; - } - /* - * Get an scb to use. - */ - if ((scb = ahc_get_scb(ahc)) == NULL) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, - dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; + target_offset = cmd->device->id + cmd->device->channel * 8; + untagged_q = &(ahc->untagged_queues[target_offset]); + if (!TAILQ_EMPTY(untagged_q)) + /* if we're already executing an untagged command + * we're busy to another */ + return SCSI_MLQUEUE_DEVICE_BUSY; + } + + /* + * Get an scb to use. + */ + if ((scb = ahc_get_scb(ahc)) == NULL) { ahc->flags |= AHC_RESOURCE_SHORTAGE; - return; - } - TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe); - cmd = &acmd_scsi_cmd(acmd); - scb->io_ctx = cmd; - scb->platform_data->dev = dev; - hscb = scb->hscb; - cmd->host_scribble = (char *)scb; + return SCSI_MLQUEUE_HOST_BUSY; + } - /* - * Fill out basics of the HSCB. - */ - hscb->control = 0; - hscb->scsiid = BUILD_SCSIID(ahc, cmd); - hscb->lun = cmd->device->lun; - mask = SCB_GET_TARGET_MASK(ahc, scb); - tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), - SCB_GET_OUR_ID(scb), - SCB_GET_TARGET(ahc, scb), &tstate); - hscb->scsirate = tinfo->scsirate; - hscb->scsioffset = tinfo->curr.offset; - if ((tstate->ultraenb & mask) != 0) - hscb->control |= ULTRAENB; - - if ((ahc->user_discenable & mask) != 0) - hscb->control |= DISCENB; - - if ((tstate->auto_negotiate & mask) != 0) { - scb->flags |= SCB_AUTO_NEGOTIATE; - scb->hscb->control |= MK_MESSAGE; - } + scb->io_ctx = cmd; + scb->platform_data->dev = dev; + hscb = scb->hscb; + cmd->host_scribble = (char *)scb; - if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { + /* + * Fill out basics of the HSCB. + */ + hscb->control = 0; + hscb->scsiid = BUILD_SCSIID(ahc, cmd); + hscb->lun = cmd->device->lun; + mask = SCB_GET_TARGET_MASK(ahc, scb); + tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), + SCB_GET_OUR_ID(scb), + SCB_GET_TARGET(ahc, scb), &tstate); + hscb->scsirate = tinfo->scsirate; + hscb->scsioffset = tinfo->curr.offset; + if ((tstate->ultraenb & mask) != 0) + hscb->control |= ULTRAENB; + + if ((ahc->user_discenable & mask) != 0) + hscb->control |= DISCENB; + + if ((tstate->auto_negotiate & mask) != 0) { + scb->flags |= SCB_AUTO_NEGOTIATE; + scb->hscb->control |= MK_MESSAGE; + } + + if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - int msg_bytes; - uint8_t tag_msgs[2]; - - msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); - if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { - hscb->control |= tag_msgs[0]; - if (tag_msgs[0] == MSG_ORDERED_TASK) - dev->commands_since_idle_or_otag = 0; - } else -#endif - if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH - && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { - hscb->control |= MSG_ORDERED_TASK; + int msg_bytes; + uint8_t tag_msgs[2]; + + msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); + if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { + hscb->control |= tag_msgs[0]; + if (tag_msgs[0] == MSG_ORDERED_TASK) dev->commands_since_idle_or_otag = 0; - } else { - hscb->control |= MSG_SIMPLE_TASK; - } - } - - hscb->cdb_len = cmd->cmd_len; - if (hscb->cdb_len <= 12) { - memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len); + } else +#endif + if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH + && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { + hscb->control |= MSG_ORDERED_TASK; + dev->commands_since_idle_or_otag = 0; } else { - memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len); - scb->flags |= SCB_CDB32_PTR; + hscb->control |= MSG_SIMPLE_TASK; } + } - scb->platform_data->xfer_len = 0; - ahc_set_residual(scb, 0); - ahc_set_sense_residual(scb, 0); - scb->sg_count = 0; - if (cmd->use_sg != 0) { - struct ahc_dma_seg *sg; - struct scatterlist *cur_seg; - struct scatterlist *end_seg; - int nseg; - - cur_seg = (struct scatterlist *)cmd->request_buffer; - nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg, - cmd->sc_data_direction); - end_seg = cur_seg + nseg; - /* Copy the segments into the SG list. */ - sg = scb->sg_list; - /* - * The sg_count may be larger than nseg if - * a transfer crosses a 32bit page. - */ - while (cur_seg < end_seg) { - dma_addr_t addr; - bus_size_t len; - int consumed; - - addr = sg_dma_address(cur_seg); - len = sg_dma_len(cur_seg); - consumed = ahc_linux_map_seg(ahc, scb, - sg, addr, len); - sg += consumed; - scb->sg_count += consumed; - cur_seg++; - } - sg--; - sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); - - /* - * Reset the sg list pointer. - */ - scb->hscb->sgptr = - ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); + hscb->cdb_len = cmd->cmd_len; + if (hscb->cdb_len <= 12) { + memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len); + } else { + memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len); + scb->flags |= SCB_CDB32_PTR; + } - /* - * Copy the first SG into the "current" - * data pointer area. - */ - scb->hscb->dataptr = scb->sg_list->addr; - scb->hscb->datacnt = scb->sg_list->len; - } else if (cmd->request_bufflen != 0) { - struct ahc_dma_seg *sg; + scb->platform_data->xfer_len = 0; + ahc_set_residual(scb, 0); + ahc_set_sense_residual(scb, 0); + scb->sg_count = 0; + if (cmd->use_sg != 0) { + struct ahc_dma_seg *sg; + struct scatterlist *cur_seg; + struct scatterlist *end_seg; + int nseg; + + cur_seg = (struct scatterlist *)cmd->request_buffer; + nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg, + cmd->sc_data_direction); + end_seg = cur_seg + nseg; + /* Copy the segments into the SG list. */ + sg = scb->sg_list; + /* + * The sg_count may be larger than nseg if + * a transfer crosses a 32bit page. + */ + while (cur_seg < end_seg) { dma_addr_t addr; - - sg = scb->sg_list; - addr = pci_map_single(ahc->dev_softc, - cmd->request_buffer, - cmd->request_bufflen, - cmd->sc_data_direction); - scb->platform_data->buf_busaddr = addr; - scb->sg_count = ahc_linux_map_seg(ahc, scb, - sg, addr, - cmd->request_bufflen); - sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); - - /* - * Reset the sg list pointer. - */ - scb->hscb->sgptr = - ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); - - /* - * Copy the first SG into the "current" - * data pointer area. - */ - scb->hscb->dataptr = sg->addr; - scb->hscb->datacnt = sg->len; - } else { - scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL); - scb->hscb->dataptr = 0; - scb->hscb->datacnt = 0; - scb->sg_count = 0; + bus_size_t len; + int consumed; + + addr = sg_dma_address(cur_seg); + len = sg_dma_len(cur_seg); + consumed = ahc_linux_map_seg(ahc, scb, + sg, addr, len); + sg += consumed; + scb->sg_count += consumed; + cur_seg++; } + sg--; + sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); - ahc_sync_sglist(ahc, scb, BUS_DMASYNC_PREWRITE); - LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); - dev->openings--; - dev->active++; - dev->commands_issued++; - if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0) - dev->commands_since_idle_or_otag++; + /* + * Reset the sg list pointer. + */ + scb->hscb->sgptr = + ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); + + /* + * Copy the first SG into the "current" + * data pointer area. + */ + scb->hscb->dataptr = scb->sg_list->addr; + scb->hscb->datacnt = scb->sg_list->len; + } else if (cmd->request_bufflen != 0) { + struct ahc_dma_seg *sg; + dma_addr_t addr; + + sg = scb->sg_list; + addr = pci_map_single(ahc->dev_softc, + cmd->request_buffer, + cmd->request_bufflen, + cmd->sc_data_direction); + scb->platform_data->buf_busaddr = addr; + scb->sg_count = ahc_linux_map_seg(ahc, scb, + sg, addr, + cmd->request_bufflen); + sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); /* - * We only allow one untagged transaction - * per target in the initiator role unless - * we are storing a full busy target *lun* - * table in SCB space. + * Reset the sg list pointer. */ - if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 - && (ahc->features & AHC_SCB_BTT) == 0) { - struct scb_tailq *untagged_q; - int target_offset; - - target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); - untagged_q = &(ahc->untagged_queues[target_offset]); - TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); - scb->flags |= SCB_UNTAGGEDQ; - if (TAILQ_FIRST(untagged_q) != scb) - continue; - } - scb->flags |= SCB_ACTIVE; - ahc_queue_scb(ahc, scb); + scb->hscb->sgptr = + ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); + + /* + * Copy the first SG into the "current" + * data pointer area. + */ + scb->hscb->dataptr = sg->addr; + scb->hscb->datacnt = sg->len; + } else { + scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL); + scb->hscb->dataptr = 0; + scb->hscb->datacnt = 0; + scb->sg_count = 0; + } + + LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); + dev->openings--; + dev->active++; + dev->commands_issued++; + if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0) + dev->commands_since_idle_or_otag++; + + scb->flags |= SCB_ACTIVE; + if (untagged_q) { + TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); + scb->flags |= SCB_UNTAGGEDQ; } + ahc_queue_scb(ahc, scb); + return 0; } /* @@ -2267,8 +2087,6 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs) ahc = (struct ahc_softc *) dev_id; ahc_lock(ahc, &flags); ours = ahc_intr(ahc); - if (ahc_linux_next_device_to_run(ahc) != NULL) - ahc_schedule_runq(ahc); ahc_linux_run_complete_queue(ahc); ahc_unlock(ahc, &flags); return IRQ_RETVAL(ours); @@ -2349,7 +2167,6 @@ ahc_linux_alloc_device(struct ahc_softc *ahc, return (NULL); memset(dev, 0, sizeof(*dev)); init_timer(&dev->timer); - TAILQ_INIT(&dev->busyq); dev->flags = AHC_DEV_UNCONFIGURED; dev->lun = lun; dev->target = targ; @@ -2515,7 +2332,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); untagged_q = &(ahc->untagged_queues[target_offset]); TAILQ_REMOVE(untagged_q, scb, links.tqe); - ahc_run_untagged_queue(ahc, untagged_q); + BUG_ON(!TAILQ_EMPTY(untagged_q)); } if ((scb->flags & SCB_ACTIVE) == 0) { @@ -2606,12 +2423,11 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) if (dev->active == 0) dev->commands_since_idle_or_otag = 0; - if (TAILQ_EMPTY(&dev->busyq)) { - if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0 - && dev->active == 0 - && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) - ahc_linux_free_device(ahc, dev); - } else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { + if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0 + && dev->active == 0 + && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) + ahc_linux_free_device(ahc, dev); + else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); dev->flags |= AHC_DEV_ON_RUN_LIST; } @@ -2940,7 +2756,6 @@ ahc_linux_release_simq(u_long arg) ahc->platform_data->qfrozen--; if (ahc->platform_data->qfrozen == 0) unblock_reqs = 1; - ahc_schedule_runq(ahc); ahc_unlock(ahc, &s); /* * There is still a race here. The mid-layer @@ -2965,11 +2780,7 @@ ahc_linux_dev_timed_unfreeze(u_long arg) dev->flags &= ~AHC_DEV_TIMER_ACTIVE; if (dev->qfrozen > 0) dev->qfrozen--; - if (dev->qfrozen == 0 - && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0) - ahc_linux_run_device_queue(ahc, dev); - if (TAILQ_EMPTY(&dev->busyq) - && dev->active == 0) + if (dev->active == 0) __ahc_linux_free_device(ahc, dev); ahc_unlock(ahc, &s); } @@ -2978,8 +2789,6 @@ static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) { struct ahc_softc *ahc; - struct ahc_cmd *acmd; - struct ahc_cmd *list_acmd; struct ahc_linux_device *dev; struct scb *pending_scb; u_long s; @@ -2998,7 +2807,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) paused = FALSE; wait = FALSE; ahc = *(struct ahc_softc **)cmd->device->host->hostdata; - acmd = (struct ahc_cmd *)cmd; printf("%s:%d:%d:%d: Attempting to queue a%s message\n", ahc_name(ahc), cmd->device->channel, @@ -3048,24 +2856,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) goto no_cmd; } - TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { - if (list_acmd == acmd) - break; - } - - if (list_acmd != NULL) { - printf("%s:%d:%d:%d: Command found on device queue\n", - ahc_name(ahc), cmd->device->channel, cmd->device->id, - cmd->device->lun); - if (flag == SCB_ABORT) { - TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); - cmd->result = DID_ABORT << 16; - ahc_linux_queue_cmd_complete(ahc, cmd); - retval = SUCCESS; - goto done; - } - } - if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, cmd->device->channel + 'A', @@ -3299,7 +3089,6 @@ done: } spin_lock_irq(&ahc->platform_data->spin_lock); } - ahc_schedule_runq(ahc); ahc_linux_run_complete_queue(ahc); ahc_midlayer_entrypoint_unlock(ahc, &s); return (retval); @@ -3308,40 +3097,6 @@ done: void ahc_platform_dump_card_state(struct ahc_softc *ahc) { - struct ahc_linux_device *dev; - int channel; - int maxchannel; - int target; - int maxtarget; - int lun; - int i; - - maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0; - maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7; - for (channel = 0; channel <= maxchannel; channel++) { - - for (target = 0; target <=maxtarget; target++) { - - for (lun = 0; lun < AHC_NUM_LUNS; lun++) { - struct ahc_cmd *acmd; - - dev = ahc_linux_get_device(ahc, channel, target, - lun, /*alloc*/FALSE); - if (dev == NULL) - continue; - - printf("DevQ(%d:%d:%d): ", - channel, target, lun); - i = 0; - TAILQ_FOREACH(acmd, &dev->busyq, - acmd_links.tqe) { - if (i++ > AHC_SCB_MAX) - break; - } - printf("%d waiting\n", i); - } - } - } } static void ahc_linux_exit(void); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index ed9027bd8a40..956097035219 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -66,11 +66,11 @@ #include #include #include +#include #include #include #include -#include /* For tasklet support. */ #include #include @@ -341,7 +341,6 @@ typedef enum { struct ahc_linux_target; struct ahc_linux_device { TAILQ_ENTRY(ahc_linux_device) links; - struct ahc_busyq busyq; /* * The number of transactions currently @@ -488,7 +487,6 @@ struct ahc_platform_data { struct ahc_completeq completeq; spinlock_t spin_lock; - struct tasklet_struct runq_tasklet; u_int qfrozen; pid_t dv_pid; struct timer_list completeq_timer; -- cgit v1.2.2 From c06716fe1cea97749668c83e8374b453fbd00823 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 16 May 2005 18:51:13 +0200 Subject: [SCSI] aic7xxx: remove some DV leftovers Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 956097035219..6ea2bfb8820c 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -488,15 +488,9 @@ struct ahc_platform_data { spinlock_t spin_lock; u_int qfrozen; - pid_t dv_pid; struct timer_list completeq_timer; struct timer_list reset_timer; struct semaphore eh_sem; - struct semaphore dv_sem; - struct semaphore dv_cmd_sem; /* XXX This needs to be in - * the target struct - */ - struct scsi_device *dv_scsi_dev; struct Scsi_Host *host; /* pointer to scsi host */ #define AHC_LINUX_NOIRQ ((uint32_t)~0) uint32_t irq; /* IRQ for this adapter */ -- cgit v1.2.2 From dedd831081052028f35aaf924ea3d6c55109074f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 16 May 2005 18:52:06 +0200 Subject: [SCSI] aic7xxx: remove Linux 2.4 ifdefs There's not much sense in sharing code anymore now that aic7xxx uses various transport class facilities. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7770_osm.c | 52 +----- drivers/scsi/aic7xxx/aic7xxx_osm.c | 314 +-------------------------------- drivers/scsi/aic7xxx/aic7xxx_osm.h | 89 ---------- drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 9 +- drivers/scsi/aic7xxx/aic7xxx_proc.c | 13 -- 5 files changed, 5 insertions(+), 472 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c index c2b47f2bdffd..682ca0b32b44 100644 --- a/drivers/scsi/aic7xxx/aic7770_osm.c +++ b/drivers/scsi/aic7xxx/aic7770_osm.c @@ -41,7 +41,6 @@ #include "aic7xxx_osm.h" -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) #include #include @@ -62,13 +61,6 @@ static struct eisa_driver aic7770_driver = { }; typedef struct device *aic7770_dev_t; -#else -#define MINSLOT 1 -#define NUMSLOTS 16 -#define IDOFFSET 0x80 - -typedef void *aic7770_dev_t; -#endif static int aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev, u_int eisaBase); @@ -76,7 +68,6 @@ static int aic7770_linux_config(struct aic7770_identity *entry, int ahc_linux_eisa_init(void) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) struct eisa_device_id *eid; struct aic7770_identity *id; int i; @@ -110,44 +101,6 @@ ahc_linux_eisa_init(void) eid->sig[0] = 0; return eisa_driver_register(&aic7770_driver); -#else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */ - struct aic7770_identity *entry; - u_int slot; - u_int eisaBase; - u_int i; - int ret = -ENODEV; - - if (aic7xxx_probe_eisa_vl == 0) - return ret; - - eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET; - for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) { - uint32_t eisa_id; - size_t id_size; - - if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0) - continue; - - eisa_id = 0; - id_size = sizeof(eisa_id); - for (i = 0; i < 4; i++) { - /* VLcards require priming*/ - outb(0x80 + i, eisaBase + IDOFFSET); - eisa_id |= inb(eisaBase + IDOFFSET + i) - << ((id_size-i-1) * 8); - } - release_region(eisaBase, AHC_EISA_IOSIZE); - if (eisa_id & 0x80000000) - continue; /* no EISA card in slot */ - - entry = aic7770_find_device(eisa_id); - if (entry != NULL) { - aic7770_linux_config(entry, NULL, eisaBase); - ret = 0; - } - } - return ret; -#endif } void @@ -187,11 +140,10 @@ aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev, ahc_free(ahc); return (error); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + dev->driver_data = (void *)ahc; if (aic7xxx_detect_complete) error = ahc_linux_register_host(ahc, &aic7xxx_driver_template); -#endif return (error); } @@ -225,7 +177,6 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq) return (-error); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int aic7770_eisa_dev_probe(struct device *dev) { @@ -261,4 +212,3 @@ aic7770_eisa_dev_remove(struct device *dev) return (0); } -#endif diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 9017942407d8..37fda70b5435 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -134,11 +134,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; #include "aiclib.c" #include /* __setup */ - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -#include "sd.h" /* For geometry detection */ -#endif - #include /* For fetching system memory size */ #include /* For block_size() */ #include /* For ssleep/msleep */ @@ -148,11 +143,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; */ spinlock_t ahc_list_spinlock; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -/* For dynamic sglist size calculation. */ -u_int ahc_linux_nseg; -#endif - /* * Set this to the delay in seconds after SCSI bus reset. * Note, we honor this only for the initial bus reset. @@ -443,7 +433,6 @@ static void ahc_linux_release_simq(u_long arg); static void ahc_linux_dev_timed_unfreeze(u_long arg); static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); -static void ahc_linux_size_nseg(void); static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo); @@ -519,11 +508,9 @@ static struct ahc_cmd * ahc_linux_run_complete_queue(struct ahc_softc *ahc) { struct ahc_cmd *acmd; - u_long done_flags; int with_errors; with_errors = 0; - ahc_done_lock(ahc, &done_flags); while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) { Scsi_Cmnd *cmd; @@ -549,7 +536,6 @@ ahc_linux_run_complete_queue(struct ahc_softc *ahc) cmd->scsi_done(cmd); } - ahc_done_unlock(ahc, &done_flags); return (acmd); } @@ -600,7 +586,6 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, static int ahc_linux_detect(Scsi_Host_Template *); static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); static const char *ahc_linux_info(struct Scsi_Host *); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int ahc_linux_slave_alloc(Scsi_Device *); static int ahc_linux_slave_configure(Scsi_Device *); static void ahc_linux_slave_destroy(Scsi_Device *); @@ -609,79 +594,10 @@ static int ahc_linux_biosparam(struct scsi_device*, struct block_device*, sector_t, int[]); #endif -#else -static int ahc_linux_release(struct Scsi_Host *); -static void ahc_linux_select_queue_depth(struct Scsi_Host *host, - Scsi_Device *scsi_devs); -#if defined(__i386__) -static int ahc_linux_biosparam(Disk *, kdev_t, int[]); -#endif -#endif static int ahc_linux_bus_reset(Scsi_Cmnd *); static int ahc_linux_dev_reset(Scsi_Cmnd *); static int ahc_linux_abort(Scsi_Cmnd *); -/* - * Calculate a safe value for AHC_NSEG (as expressed through ahc_linux_nseg). - * - * In pre-2.5.X... - * The midlayer allocates an S/G array dynamically when a command is issued - * using SCSI malloc. This array, which is in an OS dependent format that - * must later be copied to our private S/G list, is sized to house just the - * number of segments needed for the current transfer. Since the code that - * sizes the SCSI malloc pool does not take into consideration fragmentation - * of the pool, executing transactions numbering just a fraction of our - * concurrent transaction limit with list lengths aproaching AHC_NSEG will - * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the - * mid-layer does not properly handle this scsi malloc failures for the S/G - * array and the result can be a lockup of the I/O subsystem. We try to size - * our S/G list so that it satisfies our drivers allocation requirements in - * addition to avoiding fragmentation of the SCSI malloc pool. - */ -static void -ahc_linux_size_nseg(void) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - u_int cur_size; - u_int best_size; - - /* - * The SCSI allocator rounds to the nearest 512 bytes - * an cannot allocate across a page boundary. Our algorithm - * is to start at 1K of scsi malloc space per-command and - * loop through all factors of the PAGE_SIZE and pick the best. - */ - best_size = 0; - for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) { - u_int nseg; - - nseg = cur_size / sizeof(struct scatterlist); - if (nseg < AHC_LINUX_MIN_NSEG) - continue; - - if (best_size == 0) { - best_size = cur_size; - ahc_linux_nseg = nseg; - } else { - u_int best_rem; - u_int cur_rem; - - /* - * Compare the traits of the current "best_size" - * with the current size to determine if the - * current size is a better size. - */ - best_rem = best_size % sizeof(struct scatterlist); - cur_rem = cur_size % sizeof(struct scatterlist); - if (cur_rem < best_rem) { - best_size = cur_size; - ahc_linux_nseg = nseg; - } - } - } -#endif -} - /* * Try to detect an Adaptec 7XXX controller. */ @@ -691,14 +607,6 @@ ahc_linux_detect(Scsi_Host_Template *template) struct ahc_softc *ahc; int found = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); -#endif - /* * Sanity checking of Linux SCSI data structures so * that some of our hacks^H^H^H^H^Hassumptions aren't @@ -710,7 +618,6 @@ ahc_linux_detect(Scsi_Host_Template *template) printf("ahc_linux_detect: Unable to attach\n"); return (0); } - ahc_linux_size_nseg(); /* * If we've been passed any parameters, process them now. */ @@ -739,48 +646,11 @@ ahc_linux_detect(Scsi_Host_Template *template) found++; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif aic7xxx_detect_complete++; return (found); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -/* - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - */ -int -ahc_linux_release(struct Scsi_Host * host) -{ - struct ahc_softc *ahc; - u_long l; - - ahc_list_lock(&l); - if (host != NULL) { - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); - if (ahc != NULL) { - u_long s; - - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, FALSE); - ahc_unlock(ahc, &s); - ahc_free(ahc); - } - } - ahc_list_unlock(&l); - return (0); -} -#endif - /* * Return a string describing the driver. */ @@ -843,7 +713,6 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) return ahc_linux_run_command(ahc, dev, cmd); } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) static int ahc_linux_slave_alloc(Scsi_Device *device) { @@ -860,12 +729,10 @@ ahc_linux_slave_configure(Scsi_Device *device) { struct ahc_softc *ahc; struct ahc_linux_device *dev; - u_long flags; ahc = *((struct ahc_softc **)device->host->hostdata); if (bootverbose) printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id); - ahc_midlayer_entrypoint_lock(ahc, &flags); /* * Since Linux has attached to the device, configure * it so we don't free and allocate the device @@ -879,7 +746,6 @@ ahc_linux_slave_configure(Scsi_Device *device) dev->scsi_device = device; ahc_linux_device_queue_depth(ahc, dev); } - ahc_midlayer_entrypoint_unlock(ahc, &flags); /* Initial Domain Validation */ if (!spi_initial_dv(device->sdev_target)) @@ -893,12 +759,10 @@ ahc_linux_slave_destroy(Scsi_Device *device) { struct ahc_softc *ahc; struct ahc_linux_device *dev; - u_long flags; ahc = *((struct ahc_softc **)device->host->hostdata); if (bootverbose) printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id); - ahc_midlayer_entrypoint_lock(ahc, &flags); dev = ahc_linux_get_device(ahc, device->channel, device->id, device->lun, /*alloc*/FALSE); @@ -916,93 +780,17 @@ ahc_linux_slave_destroy(Scsi_Device *device) && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) ahc_linux_free_device(ahc, dev); } - ahc_midlayer_entrypoint_unlock(ahc, &flags); } -#else -/* - * Sets the queue depth for each SCSI device hanging - * off the input host adapter. - */ -static void -ahc_linux_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) -{ - Scsi_Device *device; - Scsi_Device *ldev; - struct ahc_softc *ahc; - u_long flags; - - ahc = *((struct ahc_softc **)host->hostdata); - ahc_lock(ahc, &flags); - for (device = scsi_devs; device != NULL; device = device->next) { - - /* - * Watch out for duplicate devices. This works around - * some quirks in how the SCSI scanning code does its - * device management. - */ - for (ldev = scsi_devs; ldev != device; ldev = ldev->next) { - if (ldev->host == device->host - && ldev->channel == device->channel - && ldev->id == device->id - && ldev->lun == device->lun) - break; - } - /* Skip duplicate. */ - if (ldev != device) - continue; - - if (device->host == host) { - struct ahc_linux_device *dev; - - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahc_linux_get_device(ahc, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHC_DEV_UNCONFIGURED; - dev->scsi_device = device; - ahc_linux_device_queue_depth(ahc, dev); - device->queue_depth = dev->openings - + dev->active; - if ((dev->flags & (AHC_DEV_Q_BASIC - | AHC_DEV_Q_TAGGED)) == 0) { - /* - * We allow the OS to queue 2 untagged - * transactions to us at any time even - * though we can only execute them - * serially on the controller/device. - * This should remove some latency. - */ - device->queue_depth = 2; - } - } - } - } - ahc_unlock(ahc, &flags); -} -#endif #if defined(__i386__) /* * Return the disk geometry for the given SCSI device. */ static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]) { uint8_t *bh; -#else -ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) -{ - struct scsi_device *sdev = disk->device; - u_long capacity = disk->capacity; - struct buffer_head *bh; -#endif int heads; int sectors; int cylinders; @@ -1014,22 +802,11 @@ ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) ahc = *((struct ahc_softc **)sdev->host->hostdata); channel = sdev->channel; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) bh = scsi_bios_ptable(bdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); -#else - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); -#endif - if (bh) { ret = scsi_partsize(bh, capacity, &geom[2], &geom[0], &geom[1]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) kfree(bh); -#else - brelse(bh); -#endif if (ret != -1) return (ret); } @@ -1090,15 +867,12 @@ static int ahc_linux_bus_reset(Scsi_Cmnd *cmd) { struct ahc_softc *ahc; - u_long s; int found; ahc = *(struct ahc_softc **)cmd->device->host->hostdata; - ahc_midlayer_entrypoint_lock(ahc, &s); found = ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate reset*/TRUE); ahc_linux_run_complete_queue(ahc); - ahc_midlayer_entrypoint_unlock(ahc, &s); if (bootverbose) printf("%s: SCSI bus reset delivered. " @@ -1461,11 +1235,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) *((struct ahc_softc **)host->hostdata) = ahc; ahc_lock(ahc, &s); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) scsi_assign_lock(host, &ahc->platform_data->spin_lock); -#elif AHC_SCSI_HAS_HOST_LOCK != 0 - host->lock = &ahc->platform_data->spin_lock; -#endif ahc->platform_data->host = host; host->can_queue = AHC_MAX_QUEUE; host->cmd_per_lun = 2; @@ -1484,19 +1254,14 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) ahc_set_name(ahc, new_name); } host->unique_id = ahc->unit; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - scsi_set_pci_device(host, ahc->dev_softc); -#endif ahc_linux_initialize_scsi_bus(ahc); ahc_intr_enable(ahc, TRUE); ahc_unlock(ahc, &s); host->transportt = ahc_linux_transport_template; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */ scsi_scan_host(host); -#endif return (0); } @@ -1619,7 +1384,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) ahc->platform_data->irq = AHC_LINUX_NOIRQ; ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; ahc_lockinit(ahc); - ahc_done_lockinit(ahc); init_timer(&ahc->platform_data->completeq_timer); ahc->platform_data->completeq_timer.data = (u_long)ahc; ahc->platform_data->completeq_timer.function = @@ -1643,9 +1407,7 @@ ahc_platform_free(struct ahc_softc *ahc) if (ahc->platform_data != NULL) { del_timer_sync(&ahc->platform_data->completeq_timer); if (ahc->platform_data->host != NULL) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) scsi_remove_host(ahc->platform_data->host); -#endif scsi_host_put(ahc->platform_data->host); } @@ -1681,16 +1443,7 @@ ahc_platform_free(struct ahc_softc *ahc) release_mem_region(ahc->platform_data->mem_busaddr, 0x1000); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - /* - * In 2.4 we detach from the scsi midlayer before the PCI - * layer invokes our remove callback. No per-instance - * detach is provided, so we must reach inside the PCI - * subsystem's internals and detach our driver manually. - */ - if (ahc->dev_softc != NULL) - ahc->dev_softc->driver = NULL; -#endif + free(ahc->platform_data, M_DEVBUF); } } @@ -1767,7 +1520,6 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, dev->maxtags = 0; dev->openings = 1 - dev->active; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) if (dev->scsi_device != NULL) { switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { case AHC_DEV_Q_BASIC: @@ -1793,7 +1545,6 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, break; } } -#endif } int @@ -1948,7 +1699,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, } if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) int msg_bytes; uint8_t tag_msgs[2]; @@ -1957,10 +1707,8 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, hscb->control |= tag_msgs[0]; if (tag_msgs[0] == MSG_ORDERED_TASK) dev->commands_since_idle_or_otag = 0; - } else -#endif - if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH - && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { + } else if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH + && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { hscb->control |= MSG_ORDERED_TASK; dev->commands_since_idle_or_otag = 0; } else { @@ -2280,28 +2028,9 @@ ahc_send_async(struct ahc_softc *ahc, char channel, } case AC_SENT_BDR: { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) WARN_ON(lun != CAM_LUN_WILDCARD); scsi_report_device_reset(ahc->platform_data->host, channel - 'A', target); -#else - Scsi_Device *scsi_dev; - - /* - * Find the SCSI device associated with this - * request and indicate that a UA is expected. - */ - for (scsi_dev = ahc->platform_data->host->host_queue; - scsi_dev != NULL; scsi_dev = scsi_dev->next) { - if (channel - 'A' == scsi_dev->channel - && target == scsi_dev->id - && (lun == CAM_LUN_WILDCARD - || lun == scsi_dev->lun)) { - scsi_dev->was_reset = 1; - scsi_dev->expecting_cc_ua = 1; - } - } -#endif break; } case AC_BUS_RESET: @@ -2791,7 +2520,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) struct ahc_softc *ahc; struct ahc_linux_device *dev; struct scb *pending_scb; - u_long s; u_int saved_scbptr; u_int active_scb_index; u_int last_phase; @@ -2818,22 +2546,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) printf(" 0x%x", cmd->cmnd[cdb_byte]); printf("\n"); - /* - * In all versions of Linux, we have to work around - * a major flaw in how the mid-layer is locked down - * if we are to sleep successfully in our error handler - * while allowing our interrupt handler to run. Since - * the midlayer acquires either the io_request_lock or - * our lock prior to calling us, we must use the - * spin_unlock_irq() method for unlocking our lock. - * This will force interrupts to be enabled on the - * current CPU. Since the EH thread should not have - * been running with CPU interrupts disabled other than - * by acquiring either the io_request_lock or our own - * lock, this *should* be safe. - */ - ahc_midlayer_entrypoint_lock(ahc, &s); - /* * First determine if we currently own this command. * Start by searching the device queue. If not found @@ -3090,7 +2802,6 @@ done: spin_lock_irq(&ahc->platform_data->spin_lock); } ahc_linux_run_complete_queue(ahc); - ahc_midlayer_entrypoint_unlock(ahc, &s); return (retval); } @@ -3357,7 +3068,6 @@ static struct spi_function_template ahc_linux_transport_functions = { static int __init ahc_linux_init(void) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions); if (!ahc_linux_transport_template) return -ENODEV; @@ -3366,29 +3076,11 @@ ahc_linux_init(void) spi_release_transport(ahc_linux_transport_template); ahc_linux_exit(); return -ENODEV; -#else - scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template); - if (aic7xxx_driver_template.present == 0) { - scsi_unregister_module(MODULE_SCSI_HA, - &aic7xxx_driver_template); - return (-ENODEV); - } - - return (0); -#endif } static void ahc_linux_exit(void) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - /* - * In 2.4 we have to unregister from the PCI core _after_ - * unregistering from the scsi midlayer to avoid dangling - * references. - */ - scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template); -#endif ahc_linux_pci_exit(); ahc_linux_eisa_exit(); spi_release_transport(ahc_linux_transport_template); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 6ea2bfb8820c..752022e4d4d4 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -281,12 +281,6 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec) /***************************** SMP support ************************************/ #include -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) -#define AHC_SCSI_HAS_HOST_LOCK 1 -#else -#define AHC_SCSI_HAS_HOST_LOCK 0 -#endif - #define AIC7XXX_DRIVER_VERSION "6.2.36" /**************************** Front End Queues ********************************/ @@ -438,18 +432,7 @@ struct ahc_linux_target { * manner and are allocated below 4GB, the number of S/G segments is * unrestricted. */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -/* - * We dynamically adjust the number of segments in pre-2.5 kernels to - * avoid fragmentation issues in the SCSI mid-layer's private memory - * allocator. See aic7xxx_osm.c ahc_linux_size_nseg() for details. - */ -extern u_int ahc_linux_nseg; -#define AHC_NSEG ahc_linux_nseg -#define AHC_LINUX_MIN_NSEG 64 -#else #define AHC_NSEG 128 -#endif /* * Per-SCB OSM storage. @@ -607,17 +590,6 @@ static __inline void ahc_lockinit(struct ahc_softc *); static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags); static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags); -/* Lock acquisition and release of the above lock in midlayer entry points. */ -static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *, - unsigned long *flags); -static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *, - unsigned long *flags); - -/* Lock held during command compeletion to the upper layer */ -static __inline void ahc_done_lockinit(struct ahc_softc *); -static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags); -static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags); - /* Lock held during ahc_list manipulation and ahc softc frees */ extern spinlock_t ahc_list_spinlock; static __inline void ahc_list_lockinit(void); @@ -642,57 +614,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags); } -static __inline void -ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags) -{ - /* - * In 2.5.X and some 2.4.X versions, the midlayer takes our - * lock just before calling us, so we avoid locking again. - * For other kernel versions, the io_request_lock is taken - * just before our entry point is called. In this case, we - * trade the io_request_lock for our per-softc lock. - */ -#if AHC_SCSI_HAS_HOST_LOCK == 0 - spin_unlock(&io_request_lock); - spin_lock(&ahc->platform_data->spin_lock); -#endif -} - -static __inline void -ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags) -{ -#if AHC_SCSI_HAS_HOST_LOCK == 0 - spin_unlock(&ahc->platform_data->spin_lock); - spin_lock(&io_request_lock); -#endif -} - -static __inline void -ahc_done_lockinit(struct ahc_softc *ahc) -{ - /* - * In 2.5.X, our own lock is held during completions. - * In previous versions, the io_request_lock is used. - * In either case, we can't initialize this lock again. - */ -} - -static __inline void -ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags) -{ -#if AHC_SCSI_HAS_HOST_LOCK == 0 - spin_lock_irqsave(&io_request_lock, *flags); -#endif -} - -static __inline void -ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags) -{ -#if AHC_SCSI_HAS_HOST_LOCK == 0 - spin_unlock_irqrestore(&io_request_lock, *flags); -#endif -} - static __inline void ahc_list_lockinit(void) { @@ -759,12 +680,6 @@ typedef enum } ahc_power_state; /**************************** VL/EISA Routines ********************************/ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \ - && (defined(__i386__) || defined(__alpha__)) \ - && (!defined(CONFIG_EISA))) -#define CONFIG_EISA -#endif - #ifdef CONFIG_EISA extern uint32_t aic7xxx_probe_eisa_vl; int ahc_linux_eisa_init(void); @@ -880,12 +795,8 @@ ahc_flush_device_writes(struct ahc_softc *ahc) } /**************************** Proc FS Support *********************************/ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -int ahc_linux_proc_info(char *, char **, off_t, int, int, int); -#else int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int); -#endif /*************************** Domain Validation ********************************/ /*********************** Transaction Access Wrappers *************************/ diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 6f6674aa31ef..886f92f91846 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -236,15 +236,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return (-error); } pci_set_drvdata(pdev, ahc); - if (aic7xxx_detect_complete) { -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + if (aic7xxx_detect_complete) ahc_linux_register_host(ahc, &aic7xxx_driver_template); -#else - printf("aic7xxx: ignoring PCI device found after " - "initialization\n"); - return (-ENODEV); -#endif - } return (0); } diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index 85e80eecc9d0..5fece859fbd9 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -289,13 +289,8 @@ done: * Return information to handle /proc support for the driver. */ int -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -ahc_linux_proc_info(char *buffer, char **start, off_t offset, - int length, int hostno, int inout) -#else ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, int length, int inout) -#endif { struct ahc_softc *ahc; struct info_str info; @@ -307,15 +302,7 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, retval = -EINVAL; ahc_list_lock(&s); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - TAILQ_FOREACH(ahc, &ahc_tailq, links) { - if (ahc->platform_data->host->host_no == hostno) - break; - } -#else ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata); -#endif - if (ahc == NULL) goto done; -- cgit v1.2.2 From 7dfa0f2673c17334c5de75a449f7bc161c9bd2c0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 16 May 2005 18:54:12 +0200 Subject: [SCSI] remove dma_mask hacks pci_alloc_consistent is under 4G by default. Also simplify the definition of bus_dmamap_t. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 43 ++++------------------------------ drivers/scsi/aic7xxx/aic7xxx_osm.h | 7 +----- drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 2 -- 3 files changed, 6 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 37fda70b5435..717401b26b6f 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -949,37 +949,11 @@ int ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, int flags, bus_dmamap_t *mapp) { - bus_dmamap_t map; - - map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); - if (map == NULL) - return (ENOMEM); - /* - * Although we can dma data above 4GB, our - * "consistent" memory is below 4GB for - * space efficiency reasons (only need a 4byte - * address). For this reason, we have to reset - * our dma mask when doing allocations. - */ - if (ahc->dev_softc != NULL) - if (pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF)) { - printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); - kfree(map); - return (ENODEV); - } *vaddr = pci_alloc_consistent(ahc->dev_softc, - dmat->maxsize, &map->bus_addr); - if (ahc->dev_softc != NULL) - if (pci_set_dma_mask(ahc->dev_softc, - ahc->platform_data->hw_dma_mask)) { - printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); - kfree(map); - return (ENODEV); - } + dmat->maxsize, mapp); if (*vaddr == NULL) - return (ENOMEM); - *mapp = map; - return(0); + return ENOMEM; + return 0; } void @@ -987,7 +961,7 @@ ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, void* vaddr, bus_dmamap_t map) { pci_free_consistent(ahc->dev_softc, dmat->maxsize, - vaddr, map->bus_addr); + vaddr, map); } int @@ -1001,7 +975,7 @@ ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, */ bus_dma_segment_t stack_sg; - stack_sg.ds_addr = map->bus_addr; + stack_sg.ds_addr = map; stack_sg.ds_len = dmat->maxsize; cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); return (0); @@ -1010,12 +984,6 @@ ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, void ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) { - /* - * The map may is NULL in our < 2.3.X implementation. - * Now it's 2.6.5, but just in case... - */ - BUG_ON(map == NULL); - free(map, M_DEVBUF); } int @@ -1382,7 +1350,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) TAILQ_INIT(&ahc->platform_data->completeq); TAILQ_INIT(&ahc->platform_data->device_runq); ahc->platform_data->irq = AHC_LINUX_NOIRQ; - ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; ahc_lockinit(ahc); init_timer(&ahc->platform_data->completeq_timer); ahc->platform_data->completeq_timer.data = (u_long)ahc; diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 752022e4d4d4..9cfb46b4b15f 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -174,11 +174,7 @@ struct ahc_linux_dma_tag }; typedef struct ahc_linux_dma_tag* bus_dma_tag_t; -struct ahc_linux_dmamap -{ - dma_addr_t bus_addr; -}; -typedef struct ahc_linux_dmamap* bus_dmamap_t; +typedef dma_addr_t bus_dmamap_t; typedef int bus_dma_filter_t(void*, dma_addr_t); typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); @@ -479,7 +475,6 @@ struct ahc_platform_data { uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ - uint64_t hw_dma_mask; ahc_linux_softc_flags flags; }; diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 886f92f91846..2a0ebce83e7a 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -221,13 +221,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) && ahc_linux_get_memsize() > 0x80000000 && pci_set_dma_mask(pdev, mask_39bit) == 0) { ahc->flags |= AHC_39BIT_ADDRESSING; - ahc->platform_data->hw_dma_mask = mask_39bit; } else { if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); return (-ENODEV); } - ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK; } ahc->dev_softc = pci; error = ahc_pci_config(ahc, entry); -- cgit v1.2.2 From 013791ee01754f83dbb4ccfd266381db74e120b5 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 16 May 2005 18:52:39 +0200 Subject: [SCSI] aic7xxx: remove usage of obsolete typedefs Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 52 +++++++++++++------------------------- drivers/scsi/aic7xxx/aic7xxx_osm.h | 36 ++++++++++++++------------ drivers/scsi/aic7xxx/aiclib.c | 1 - 3 files changed, 38 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 717401b26b6f..ff2a212c6e9c 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -426,12 +426,12 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *, struct ahc_linux_device *, struct scb *); static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, - Scsi_Cmnd *cmd); + struct scsi_cmnd *cmd); static void ahc_linux_sem_timeout(u_long arg); static void ahc_linux_freeze_simq(struct ahc_softc *ahc); static void ahc_linux_release_simq(u_long arg); static void ahc_linux_dev_timed_unfreeze(u_long arg); -static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag); +static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, @@ -512,7 +512,7 @@ ahc_linux_run_complete_queue(struct ahc_softc *ahc) with_errors = 0; while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) { - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) { /* @@ -542,7 +542,7 @@ ahc_linux_run_complete_queue(struct ahc_softc *ahc) static __inline void ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) { - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; cmd = scb->io_ctx; ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE); @@ -582,27 +582,11 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, return (consumed); } -/************************ Host template entry points *************************/ -static int ahc_linux_detect(Scsi_Host_Template *); -static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); -static const char *ahc_linux_info(struct Scsi_Host *); -static int ahc_linux_slave_alloc(Scsi_Device *); -static int ahc_linux_slave_configure(Scsi_Device *); -static void ahc_linux_slave_destroy(Scsi_Device *); -#if defined(__i386__) -static int ahc_linux_biosparam(struct scsi_device*, - struct block_device*, - sector_t, int[]); -#endif -static int ahc_linux_bus_reset(Scsi_Cmnd *); -static int ahc_linux_dev_reset(Scsi_Cmnd *); -static int ahc_linux_abort(Scsi_Cmnd *); - /* * Try to detect an Adaptec 7XXX controller. */ static int -ahc_linux_detect(Scsi_Host_Template *template) +ahc_linux_detect(struct scsi_host_template *template) { struct ahc_softc *ahc; int found = 0; @@ -683,7 +667,7 @@ ahc_linux_info(struct Scsi_Host *host) * Queue an SCB to the controller. */ static int -ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) +ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) { struct ahc_softc *ahc; struct ahc_linux_device *dev; @@ -714,7 +698,7 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) } static int -ahc_linux_slave_alloc(Scsi_Device *device) +ahc_linux_slave_alloc(struct scsi_device *device) { struct ahc_softc *ahc; @@ -725,7 +709,7 @@ ahc_linux_slave_alloc(Scsi_Device *device) } static int -ahc_linux_slave_configure(Scsi_Device *device) +ahc_linux_slave_configure(struct scsi_device *device) { struct ahc_softc *ahc; struct ahc_linux_device *dev; @@ -755,7 +739,7 @@ ahc_linux_slave_configure(Scsi_Device *device) } static void -ahc_linux_slave_destroy(Scsi_Device *device) +ahc_linux_slave_destroy(struct scsi_device *device) { struct ahc_softc *ahc; struct ahc_linux_device *dev; @@ -836,7 +820,7 @@ ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, * Abort the current SCSI command(s). */ static int -ahc_linux_abort(Scsi_Cmnd *cmd) +ahc_linux_abort(struct scsi_cmnd *cmd) { int error; @@ -850,7 +834,7 @@ ahc_linux_abort(Scsi_Cmnd *cmd) * Attempt to send a target reset message to the device that timed out. */ static int -ahc_linux_dev_reset(Scsi_Cmnd *cmd) +ahc_linux_dev_reset(struct scsi_cmnd *cmd) { int error; @@ -864,7 +848,7 @@ ahc_linux_dev_reset(Scsi_Cmnd *cmd) * Reset the SCSI bus. */ static int -ahc_linux_bus_reset(Scsi_Cmnd *cmd) +ahc_linux_bus_reset(struct scsi_cmnd *cmd) { struct ahc_softc *ahc; int found; @@ -881,7 +865,7 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd) return SUCCESS; } -Scsi_Host_Template aic7xxx_driver_template = { +struct scsi_host_template aic7xxx_driver_template = { .module = THIS_MODULE, .name = "aic7xxx", .proc_info = ahc_linux_proc_info, @@ -1189,7 +1173,7 @@ __setup("aic7xxx=", aic7xxx_setup); uint32_t aic7xxx_verbose; int -ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) +ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template) { char buf[80]; struct Scsi_Host *host; @@ -2017,7 +2001,7 @@ ahc_send_async(struct ahc_softc *ahc, char channel, void ahc_done(struct ahc_softc *ahc, struct scb *scb) { - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; struct ahc_linux_device *dev; LIST_REMOVE(scb, pending_links); @@ -2171,7 +2155,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, case SCSI_STATUS_CHECK_COND: case SCSI_STATUS_CMD_TERMINATED: { - Scsi_Cmnd *cmd; + struct scsi_cmnd *cmd; /* * Copy sense information to the OS's cmd @@ -2293,7 +2277,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, } static void -ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) +ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) { /* * Typically, the complete queue has very few entries @@ -2482,7 +2466,7 @@ ahc_linux_dev_timed_unfreeze(u_long arg) } static int -ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) +ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) { struct ahc_softc *ahc; struct ahc_linux_device *dev; diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 9cfb46b4b15f..2afd0521c4ad 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -59,6 +59,7 @@ #ifndef _AIC7XXX_LINUX_H_ #define _AIC7XXX_LINUX_H_ +#include #include #include #include @@ -68,16 +69,19 @@ #include #include #include +#include #include #include -#include -#include +#include +#include +#include +#include +#include +#include /* Core SCSI definitions */ #define AIC_LIB_PREFIX ahc -#include "scsi.h" -#include /* Name space conflict with BSD queue macros */ #ifdef LIST_HEAD @@ -106,7 +110,7 @@ /************************* Forward Declarations *******************************/ struct ahc_softc; typedef struct pci_dev *ahc_dev_softc_t; -typedef Scsi_Cmnd *ahc_io_ctx_t; +typedef struct scsi_cmnd *ahc_io_ctx_t; /******************************* Byte Order ***********************************/ #define ahc_htobe16(x) cpu_to_be16(x) @@ -144,7 +148,7 @@ typedef Scsi_Cmnd *ahc_io_ctx_t; extern u_int aic7xxx_no_probe; extern u_int aic7xxx_allow_memio; extern int aic7xxx_detect_complete; -extern Scsi_Host_Template aic7xxx_driver_template; +extern struct scsi_host_template aic7xxx_driver_template; /***************************** Bus Space/DMA **********************************/ @@ -408,7 +412,7 @@ struct ahc_linux_device { #define AHC_OTAG_THRESH 500 int lun; - Scsi_Device *scsi_device; + struct scsi_device *scsi_device; struct ahc_linux_target *target; }; @@ -564,7 +568,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count) /**************************** Initialization **********************************/ int ahc_linux_register_host(struct ahc_softc *, - Scsi_Host_Template *); + struct scsi_host_template *); uint64_t ahc_linux_get_memsize(void); @@ -795,13 +799,13 @@ int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, /*************************** Domain Validation ********************************/ /*********************** Transaction Access Wrappers *************************/ -static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); +static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t); static __inline void ahc_set_transaction_status(struct scb *, uint32_t); -static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); +static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t); static __inline void ahc_set_scsi_status(struct scb *, uint32_t); -static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd); static __inline uint32_t ahc_get_transaction_status(struct scb *); -static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd); +static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd); static __inline uint32_t ahc_get_scsi_status(struct scb *); static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); static __inline u_long ahc_get_transfer_length(struct scb *); @@ -820,7 +824,7 @@ static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, static __inline void ahc_freeze_scb(struct scb *scb); static __inline -void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) +void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status) { cmd->result &= ~(CAM_STATUS_MASK << 16); cmd->result |= status << 16; @@ -833,7 +837,7 @@ void ahc_set_transaction_status(struct scb *scb, uint32_t status) } static __inline -void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) +void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status) { cmd->result &= ~0xFFFF; cmd->result |= status; @@ -846,7 +850,7 @@ void ahc_set_scsi_status(struct scb *scb, uint32_t status) } static __inline -uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd) +uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd) { return ((cmd->result >> 16) & CAM_STATUS_MASK); } @@ -858,7 +862,7 @@ uint32_t ahc_get_transaction_status(struct scb *scb) } static __inline -uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd) +uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd) { return (cmd->result & 0xFFFF); } diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c index 79bfd9efd8ed..7c5a6db0e672 100644 --- a/drivers/scsi/aic7xxx/aiclib.c +++ b/drivers/scsi/aic7xxx/aiclib.c @@ -35,7 +35,6 @@ #include /* Core SCSI definitions */ -#include "scsi.h" #include #include "aiclib.h" #include "cam.h" -- cgit v1.2.2 From 38c29ce06d24691d6e6dd786175fcc54efd5995b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 16 May 2005 21:37:58 -0500 Subject: [SCSI] aic7xxx: remove the last vestiges of the runq This was rendered obsolete by the busyq removal; remove some of the last remnants of its presence. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 5 ----- drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 -- 2 files changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index ff2a212c6e9c..d0c71da58e85 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1332,7 +1332,6 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) return (ENOMEM); memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); TAILQ_INIT(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->device_runq); ahc->platform_data->irq = AHC_LINUX_NOIRQ; ahc_lockinit(ahc); init_timer(&ahc->platform_data->completeq_timer); @@ -2107,10 +2106,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) && dev->active == 0 && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) ahc_linux_free_device(ahc, dev); - else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; - } if ((scb->flags & SCB_RECOVERY_SCB) != 0) { printf("Recovery SCB completes\n"); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 2afd0521c4ad..9ce7639dc739 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -325,7 +325,6 @@ typedef enum { AHC_DEV_UNCONFIGURED = 0x01, AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ AHC_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ - AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ @@ -466,7 +465,6 @@ struct ahc_platform_data { * Fields accessed from interrupt context. */ struct ahc_linux_target *targets[AHC_NUM_TARGETS]; - TAILQ_HEAD(, ahc_linux_device) device_runq; struct ahc_completeq completeq; spinlock_t spin_lock; -- cgit v1.2.2 From 8e45ebcc661069bfb002c56dd942aedf43ba9239 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 17 May 2005 00:06:08 -0500 Subject: [SCSI] aic7xxx: remove the completeq This should finish the spurious queue removal from aic7xxx (there are other queues that are probably unnecessary, but at least the major and obviously unnecessary ones are done with). Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 121 +------------------------------------ drivers/scsi/aic7xxx/aic7xxx_osm.h | 17 +----- 2 files changed, 5 insertions(+), 133 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index d0c71da58e85..ca796b9d737b 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -433,7 +433,6 @@ static void ahc_linux_release_simq(u_long arg); static void ahc_linux_dev_timed_unfreeze(u_long arg); static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); -static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo); static void ahc_linux_device_queue_depth(struct ahc_softc *ahc, @@ -454,29 +453,17 @@ static void ahc_linux_setup_tag_info_global(char *p); static aic_option_callback_t ahc_linux_setup_tag_info; static int aic7xxx_setup(char *s); static int ahc_linux_next_unit(void); -static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc); /********************************* Inlines ************************************/ static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, u_int lun, int alloc); -static __inline void ahc_schedule_completeq(struct ahc_softc *ahc); static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, struct ahc_dma_seg *sg, dma_addr_t addr, bus_size_t len); -static __inline void -ahc_schedule_completeq(struct ahc_softc *ahc) -{ - if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) { - ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER; - ahc->platform_data->completeq_timer.expires = jiffies; - add_timer(&ahc->platform_data->completeq_timer); - } -} - static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, u_int lun, int alloc) @@ -503,42 +490,6 @@ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, return (dev); } -#define AHC_LINUX_MAX_RETURNED_ERRORS 4 -static struct ahc_cmd * -ahc_linux_run_complete_queue(struct ahc_softc *ahc) -{ - struct ahc_cmd *acmd; - int with_errors; - - with_errors = 0; - while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) { - struct scsi_cmnd *cmd; - - if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) { - /* - * Linux uses stack recursion to requeue - * commands that need to be retried. Avoid - * blowing out the stack by "spoon feeding" - * commands that completed with error back - * the operating system in case they are going - * to be retried. "ick" - */ - ahc_schedule_completeq(ahc); - break; - } - TAILQ_REMOVE(&ahc->platform_data->completeq, - acmd, acmd_links.tqe); - cmd = &acmd_scsi_cmd(acmd); - cmd->host_scribble = NULL; - if (ahc_cmd_get_transaction_status(cmd) != DID_OK - || (cmd->result & 0xFF) != SCSI_STATUS_OK) - with_errors++; - - cmd->scsi_done(cmd); - } - return (acmd); -} - static __inline void ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) { @@ -856,7 +807,6 @@ ahc_linux_bus_reset(struct scsi_cmnd *cmd) ahc = *(struct ahc_softc **)cmd->device->host->hostdata; found = ahc_reset_channel(ahc, cmd->device->channel + 'A', /*initiate reset*/TRUE); - ahc_linux_run_complete_queue(ahc); if (bootverbose) printf("%s: SCSI bus reset delivered. " @@ -1331,13 +1281,8 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) if (ahc->platform_data == NULL) return (ENOMEM); memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); - TAILQ_INIT(&ahc->platform_data->completeq); ahc->platform_data->irq = AHC_LINUX_NOIRQ; ahc_lockinit(ahc); - init_timer(&ahc->platform_data->completeq_timer); - ahc->platform_data->completeq_timer.data = (u_long)ahc; - ahc->platform_data->completeq_timer.function = - (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue; init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); ahc->seltime = (aic7xxx_seltime & 0x3) << 4; ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; @@ -1355,7 +1300,6 @@ ahc_platform_free(struct ahc_softc *ahc) int i, j; if (ahc->platform_data != NULL) { - del_timer_sync(&ahc->platform_data->completeq_timer); if (ahc->platform_data->host != NULL) { scsi_remove_host(ahc->platform_data->host); scsi_host_put(ahc->platform_data->host); @@ -1504,18 +1448,6 @@ ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, return 0; } -static void -ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc) -{ - u_long flags; - - ahc_lock(ahc, &flags); - del_timer(&ahc->platform_data->completeq_timer); - ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER; - ahc_linux_run_complete_queue(ahc); - ahc_unlock(ahc, &flags); -} - static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { @@ -1785,7 +1717,6 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs) ahc = (struct ahc_softc *) dev_id; ahc_lock(ahc, &flags); ours = ahc_intr(ahc); - ahc_linux_run_complete_queue(ahc); ahc_unlock(ahc, &flags); return IRQ_RETVAL(ours); } @@ -1794,8 +1725,6 @@ void ahc_platform_flushwork(struct ahc_softc *ahc) { - while (ahc_linux_run_complete_queue(ahc) != NULL) - ; } static struct ahc_linux_target* @@ -2274,22 +2203,6 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) { - /* - * Typically, the complete queue has very few entries - * queued to it before the queue is emptied by - * ahc_linux_run_complete_queue, so sorting the entries - * by generation number should be inexpensive. - * We perform the sort so that commands that complete - * with an error are retuned in the order origionally - * queued to the controller so that any subsequent retries - * are performed in order. The underlying ahc routines do - * not guarantee the order that aborted commands will be - * returned to us. - */ - struct ahc_completeq *completeq; - struct ahc_cmd *list_cmd; - struct ahc_cmd *acmd; - /* * Map CAM error codes into Linux Error codes. We * avoid the conversion so that the DV code has the @@ -2343,26 +2256,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) new_status = DID_ERROR; break; case CAM_REQUEUE_REQ: - /* - * If we want the request requeued, make sure there - * are sufficent retries. In the old scsi error code, - * we used to be able to specify a result code that - * bypassed the retry count. Now we must use this - * hack. We also "fake" a check condition with - * a sense code of ABORTED COMMAND. This seems to - * evoke a retry even if this command is being sent - * via the eh thread. Ick! Ick! Ick! - */ - if (cmd->retries > 0) - cmd->retries--; - new_status = DID_OK; - ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); - cmd->result |= (DRIVER_SENSE << 24); - memset(cmd->sense_buffer, 0, - sizeof(cmd->sense_buffer)); - cmd->sense_buffer[0] = SSD_ERRCODE_VALID - | SSD_CURRENT_ERROR; - cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; + new_status = DID_REQUEUE; break; default: /* We should never get here */ @@ -2373,17 +2267,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) ahc_cmd_set_transaction_status(cmd, new_status); } - completeq = &ahc->platform_data->completeq; - list_cmd = TAILQ_FIRST(completeq); - acmd = (struct ahc_cmd *)cmd; - while (list_cmd != NULL - && acmd_scsi_cmd(list_cmd).serial_number - < acmd_scsi_cmd(acmd).serial_number) - list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); - if (list_cmd != NULL) - TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); - else - TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); + cmd->scsi_done(cmd); } static void @@ -2747,7 +2631,6 @@ done: } spin_lock_irq(&ahc->platform_data->spin_lock); } - ahc_linux_run_complete_queue(ahc); return (retval); } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 9ce7639dc739..e70c1fa47db2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -436,16 +436,11 @@ struct ahc_linux_target { /* * Per-SCB OSM storage. */ -typedef enum { - AHC_UP_EH_SEMAPHORE = 0x1 -} ahc_linux_scb_flags; - struct scb_platform_data { struct ahc_linux_device *dev; dma_addr_t buf_busaddr; uint32_t xfer_len; uint32_t sense_resid; /* Auto-Sense residual */ - ahc_linux_scb_flags flags; }; /* @@ -454,22 +449,14 @@ struct scb_platform_data { * alignment restrictions of the various platforms supported by * this driver. */ -typedef enum { - AHC_RUN_CMPLT_Q_TIMER = 0x10 -} ahc_linux_softc_flags; - -TAILQ_HEAD(ahc_completeq, ahc_cmd); - struct ahc_platform_data { /* * Fields accessed from interrupt context. */ struct ahc_linux_target *targets[AHC_NUM_TARGETS]; - struct ahc_completeq completeq; spinlock_t spin_lock; u_int qfrozen; - struct timer_list completeq_timer; struct timer_list reset_timer; struct semaphore eh_sem; struct Scsi_Host *host; /* pointer to scsi host */ @@ -477,7 +464,9 @@ struct ahc_platform_data { uint32_t irq; /* IRQ for this adapter */ uint32_t bios_address; uint32_t mem_busaddr; /* Mem Base Addr */ - ahc_linux_softc_flags flags; + +#define AHC_UP_EH_SEMAPHORE 0x1 + uint32_t flags; }; /************************** OS Utility Wrappers *******************************/ -- cgit v1.2.2 From c7525233d2df39b95552f6f49c6b390a9c4d2e80 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 17 May 2005 18:07:34 -0500 Subject: [SCSI] aic7xxx: make correct use of slave_alloc/destroy and remove the per device timer The allocation of all of our components should be done in slave alloc. Currently it's rather fancifully refcounted in the queuecommand callback. This patch moves allocation and destroy to their correct places in slave_alloc/slave_destory. Now we can guarantee that everywhere a device is requested, it's actually been allocated, so don't check for this anymore. Additionally, the per device busy timer was the only source of potential use after free. It's been deleted because Linux does the correct thing with busy returns, so there's no need to implement a separate timer in the driver. Finally, implement code that forces all the device parameters to zero (i.e. async and narrow) in the slave alloc, inform the spi class of the bios recorded maximums and wait until slave configure before trying anything more adventurous. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 183 ++++++++++++++++--------------------- drivers/scsi/aic7xxx/aic7xxx_osm.h | 8 -- 2 files changed, 79 insertions(+), 112 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index ca796b9d737b..c03f29486071 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -430,7 +430,6 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, static void ahc_linux_sem_timeout(u_long arg); static void ahc_linux_freeze_simq(struct ahc_softc *ahc); static void ahc_linux_release_simq(u_long arg); -static void ahc_linux_dev_timed_unfreeze(u_long arg); static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, @@ -457,7 +456,7 @@ static int ahc_linux_next_unit(void); /********************************* Inlines ************************************/ static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, - u_int target, u_int lun, int alloc); + u_int target, u_int lun); static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, @@ -466,7 +465,7 @@ static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, - u_int lun, int alloc) + u_int lun) { struct ahc_linux_target *targ; struct ahc_linux_device *dev; @@ -476,18 +475,9 @@ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, if (channel != 0) target_offset += 8; targ = ahc->platform_data->targets[target_offset]; - if (targ == NULL) { - if (alloc != 0) { - targ = ahc_linux_alloc_target(ahc, channel, target); - if (targ == NULL) - return (NULL); - } else - return (NULL); - } + BUG_ON(targ == NULL); dev = targ->devices[lun]; - if (dev == NULL && alloc != 0) - dev = ahc_linux_alloc_device(ahc, targ, lun); - return (dev); + return dev; } static __inline void @@ -640,7 +630,7 @@ ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) return SCSI_MLQUEUE_HOST_BUSY; dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, - cmd->device->lun, /*alloc*/TRUE); + cmd->device->lun); BUG_ON(dev == NULL); cmd->result = CAM_REQ_INPROG << 16; @@ -652,11 +642,69 @@ static int ahc_linux_slave_alloc(struct scsi_device *device) { struct ahc_softc *ahc; + struct ahc_linux_target *targ; + struct scsi_target *starget = device->sdev_target; + struct ahc_linux_device *dev; + u_int target_offset; + + target_offset = starget->id; + if (starget->channel != 0) + target_offset += 8; ahc = *((struct ahc_softc **)device->host->hostdata); if (bootverbose) printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id); - return (0); + targ = ahc->platform_data->targets[target_offset]; + if (targ == NULL) { + targ = ahc_linux_alloc_target(ahc, starget->channel, starget->id); + struct seeprom_config *sc = ahc->seep_config; + if (targ == NULL) + return -ENOMEM; + if (sc) { + unsigned short scsirate; + struct ahc_devinfo devinfo; + struct ahc_initiator_tinfo *tinfo; + struct ahc_tmode_tstate *tstate; + char channel = starget->channel + 'A'; + unsigned int our_id = ahc->our_id; + + if (starget->channel) + our_id = ahc->our_id_b; + + if ((ahc->features & AHC_ULTRA2) != 0) { + scsirate = sc->device_flags[target_offset] & CFXFER; + } else { + scsirate = (sc->device_flags[target_offset] & CFXFER) << 4; + if (sc->device_flags[target_offset] & CFSYNCH) + scsirate |= SOFS; + } + if (sc->device_flags[target_offset] & CFWIDEB) { + scsirate |= WIDEXFER; + spi_max_width(starget) = 1; + } else + spi_max_width(starget) = 0; + spi_min_period(starget) = + ahc_find_period(ahc, scsirate, AHC_SYNCRATE_DT); + tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id, + targ->target, &tstate); + ahc_compile_devinfo(&devinfo, our_id, targ->target, + CAM_LUN_WILDCARD, channel, + ROLE_INITIATOR); + ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0, + AHC_TRANS_GOAL, /*paused*/FALSE); + ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, + AHC_TRANS_GOAL, /*paused*/FALSE); + } + + } + dev = targ->devices[device->lun]; + if (dev == NULL) { + dev = ahc_linux_alloc_device(ahc, targ, device->lun); + if (dev == NULL) + return -ENOMEM; + } + + return 0; } static int @@ -666,27 +714,20 @@ ahc_linux_slave_configure(struct scsi_device *device) struct ahc_linux_device *dev; ahc = *((struct ahc_softc **)device->host->hostdata); + if (bootverbose) printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id); - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahc_linux_get_device(ahc, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHC_DEV_UNCONFIGURED; - dev->scsi_device = device; - ahc_linux_device_queue_depth(ahc, dev); - } + + dev = ahc_linux_get_device(ahc, device->channel, device->id, + device->lun); + dev->scsi_device = device; + ahc_linux_device_queue_depth(ahc, dev); /* Initial Domain Validation */ if (!spi_initial_dv(device->sdev_target)) spi_dv_device(device); - return (0); + return 0; } static void @@ -699,22 +740,11 @@ ahc_linux_slave_destroy(struct scsi_device *device) if (bootverbose) printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id); dev = ahc_linux_get_device(ahc, device->channel, - device->id, device->lun, - /*alloc*/FALSE); - /* - * Filter out "silly" deletions of real devices by only - * deleting devices that have had slave_configure() - * called on them. All other devices that have not - * been configured will automatically be deleted by - * the refcounting process. - */ - if (dev != NULL - && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) { - dev->flags |= AHC_DEV_UNCONFIGURED; - if (dev->active == 0 - && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) - ahc_linux_free_device(ahc, dev); - } + device->id, device->lun); + + BUG_ON(dev->active); + + ahc_linux_free_device(ahc, dev); } #if defined(__i386__) @@ -1361,7 +1391,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', devinfo->target, - devinfo->lun, /*alloc*/FALSE); + devinfo->lun); if (dev == NULL) return; was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); @@ -1793,8 +1823,6 @@ ahc_linux_alloc_device(struct ahc_softc *ahc, if (dev == NULL) return (NULL); memset(dev, 0, sizeof(*dev)); - init_timer(&dev->timer); - dev->flags = AHC_DEV_UNCONFIGURED; dev->lun = lun; dev->target = targ; @@ -1817,7 +1845,7 @@ ahc_linux_alloc_device(struct ahc_softc *ahc, } static void -__ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) +ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) { struct ahc_linux_target *targ; @@ -1829,13 +1857,6 @@ __ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) ahc_linux_free_target(ahc, targ); } -static void -ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) -{ - del_timer_sync(&dev->timer); - __ahc_linux_free_device(ahc, dev); -} - void ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun, ac_code code, void *arg) @@ -2008,8 +2029,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) } } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { ahc_linux_handle_scsi_status(ahc, dev, scb); - } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { - dev->flags |= AHC_DEV_UNCONFIGURED; } if (dev->openings == 1 @@ -2031,11 +2050,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) if (dev->active == 0) dev->commands_since_idle_or_otag = 0; - if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0 - && dev->active == 0 - && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) - ahc_linux_free_device(ahc, dev); - if ((scb->flags & SCB_RECOVERY_SCB) != 0) { printf("Recovery SCB completes\n"); if (ahc_get_transaction_status(scb) == CAM_BDR_SENT @@ -2174,27 +2188,6 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, ahc_platform_set_tags(ahc, &devinfo, (dev->flags & AHC_DEV_Q_BASIC) ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); - /* FALLTHROUGH */ - } - case SCSI_STATUS_BUSY: - { - /* - * Set a short timer to defer sending commands for - * a bit since Linux will not delay in this case. - */ - if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) { - printf("%s:%c:%d: Device Timer still active during " - "busy processing\n", ahc_name(ahc), - dev->target->channel, dev->target->target); - break; - } - dev->flags |= AHC_DEV_TIMER_ACTIVE; - dev->qfrozen++; - init_timer(&dev->timer); - dev->timer.data = (u_long)dev; - dev->timer.expires = jiffies + (HZ/2); - dev->timer.function = ahc_linux_dev_timed_unfreeze; - add_timer(&dev->timer); break; } } @@ -2326,24 +2319,6 @@ ahc_linux_release_simq(u_long arg) scsi_unblock_requests(ahc->platform_data->host); } -static void -ahc_linux_dev_timed_unfreeze(u_long arg) -{ - struct ahc_linux_device *dev; - struct ahc_softc *ahc; - u_long s; - - dev = (struct ahc_linux_device *)arg; - ahc = dev->target->ahc; - ahc_lock(ahc, &s); - dev->flags &= ~AHC_DEV_TIMER_ACTIVE; - if (dev->qfrozen > 0) - dev->qfrozen--; - if (dev->active == 0) - __ahc_linux_free_device(ahc, dev); - ahc_unlock(ahc, &s); -} - static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) { @@ -2384,7 +2359,7 @@ ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) * command, return success. */ dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, - cmd->device->lun, /*alloc*/FALSE); + cmd->device->lun); if (dev == NULL) { /* diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index e70c1fa47db2..30c200d5bcd5 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -322,13 +322,10 @@ struct ahc_cmd { */ TAILQ_HEAD(ahc_busyq, ahc_cmd); typedef enum { - AHC_DEV_UNCONFIGURED = 0x01, AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ - AHC_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ - AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ } ahc_linux_dev_flags; struct ahc_linux_target; @@ -373,11 +370,6 @@ struct ahc_linux_device { ahc_linux_dev_flags flags; - /* - * Per device timer. - */ - struct timer_list timer; - /* * The high limit for the tags variable. */ -- cgit v1.2.2 From fb3089dfb58bf07992252b42e77c6f35d45dff5e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Tue, 17 May 2005 21:09:52 -0500 Subject: [SCSI] aic7xxx: add back locking Tampering with the settings has to be done under the host lock ... slave_alloc isn't called under any lock, so this has to be done explicitly. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index c03f29486071..b216de41bff4 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -645,7 +645,9 @@ ahc_linux_slave_alloc(struct scsi_device *device) struct ahc_linux_target *targ; struct scsi_target *starget = device->sdev_target; struct ahc_linux_device *dev; - u_int target_offset; + unsigned int target_offset; + unsigned long flags; + int retval = -ENOMEM; target_offset = starget->id; if (starget->channel != 0) @@ -654,12 +656,14 @@ ahc_linux_slave_alloc(struct scsi_device *device) ahc = *((struct ahc_softc **)device->host->hostdata); if (bootverbose) printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id); + ahc_lock(ahc, &flags); targ = ahc->platform_data->targets[target_offset]; if (targ == NULL) { targ = ahc_linux_alloc_target(ahc, starget->channel, starget->id); struct seeprom_config *sc = ahc->seep_config; if (targ == NULL) - return -ENOMEM; + goto out; + if (sc) { unsigned short scsirate; struct ahc_devinfo devinfo; @@ -701,10 +705,13 @@ ahc_linux_slave_alloc(struct scsi_device *device) if (dev == NULL) { dev = ahc_linux_alloc_device(ahc, targ, device->lun); if (dev == NULL) - return -ENOMEM; + goto out; } + retval = 0; - return 0; + out: + ahc_unlock(ahc, &flags); + return retval; } static int -- cgit v1.2.2 From 2bf2c568c878b9c0bbacac5c3210a6bd81856d21 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Thu, 19 May 2005 21:30:13 -0500 Subject: [SCSI] aic7xxx: fix U160 mode The new period/dt setting routines don't get the coupling of these parameters correct. This means that Domain Validation never gets DT set, and thus the drive gets restricted to U80. Fix this by restoring the couplings in the set routines. Signed-off-by: James Bottomley --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index b216de41bff4..f90efa265ba2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -2679,6 +2679,11 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period) if (offset == 0) offset = MAX_OFFSET; + if (period < 9) + period = 9; /* 12.5ns is our minimum */ + if (period == 9) + ppr_options |= MSG_EXT_PPR_DT_REQ; + ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); @@ -2764,6 +2769,12 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) unsigned long flags; struct ahc_syncrate *syncrate; + if (dt) { + period = 9; /* 12.5ns is the only period valid for DT */ + ppr_options |= MSG_EXT_PPR_DT_REQ; + } else if (period == 9) + period = 10; /* if resetting DT, period must be >= 25ns */ + ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, starget->channel + 'A', ROLE_INITIATOR); syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT); -- cgit v1.2.2 From 46f4e1b7d5fa3ddf2486bf69716c404147e38ebf Mon Sep 17 00:00:00 2001 From: Peter Osterlund Date: Fri, 20 May 2005 13:59:06 -0700 Subject: [PATCH] packet driver permission checking fix If you tried to open a packet device first in read-only mode and then a second time in read-write mode, the second open succeeded even though the device was not correctly set up for writing. If you then tried to write data to the device, the writes would fail with I/O errors. This patch prevents that problem by making the second open fail with -EBUSY. Signed-off-by: Peter Osterlund Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/pktcdvd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index b9a6b7ad64f3..bc56770bcc90 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2021,7 +2021,13 @@ static int pkt_open(struct inode *inode, struct file *file) BUG_ON(pd->refcnt < 0); pd->refcnt++; - if (pd->refcnt == 1) { + if (pd->refcnt > 1) { + if ((file->f_mode & FMODE_WRITE) && + !test_bit(PACKET_WRITABLE, &pd->flags)) { + ret = -EBUSY; + goto out_dec; + } + } else { if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { ret = -EIO; goto out_dec; -- cgit v1.2.2 From 912490db699d83cb3d03570b63df7448677a3f56 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sat, 21 May 2005 10:27:02 +0100 Subject: [PATCH] MMC: Proper MMC command classes support Defines for the different command classes as defined in the MMC and SD specifications. Removes the check for high command classes and instead checks that the command classes needed are present. Previous solution killed forward compatibility at no apparent gain. Signed-of-by: Pierre Ossman --- drivers/mmc/mmc_block.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index b5b4a7b11903..d4eee99c2bf6 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -383,7 +383,10 @@ static int mmc_blk_probe(struct mmc_card *card) struct mmc_blk_data *md; int err; - if (card->csd.cmdclass & ~0x1ff) + /* + * Check that the card supports the command class(es) we need. + */ + if (!(card->csd.cmdclass & CCC_BLOCK_READ)) return -ENODEV; if (card->csd.read_blkbits < 9) { -- cgit v1.2.2 From 857dde2e79082d2954ede7f10783addaae956777 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 21 May 2005 15:52:23 +0100 Subject: When we detect that a 16550 was in fact part of a NatSemi SuperIO chip with high-speed mode enabled, we switch it to high-speed mode so that baud_base becomes 921600. However, we also need to multiply the baud divisor by 8 at the same time, in case it's already in use as a console. Signed-off-by: David Woodhouse Acked-by: Tom Rini Signed-off-by: Russell King --- drivers/serial/8250.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 3bbf0cc6e53f..30e8beb71430 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -682,8 +682,6 @@ static void autoconfig_16550a(struct uart_8250_port *up) * from EXCR1. Switch back to bank 0, change it in MCR. Then * switch back to bank 2, read it from EXCR1 again and check * it's changed. If so, set baud_base in EXCR2 to 921600. -- dwmw2 - * On PowerPC we don't want to change baud_base, as we have - * a number of different divisors. -- Tom Rini */ serial_outp(up, UART_LCR, 0); status1 = serial_in(up, UART_MCR); @@ -699,16 +697,25 @@ static void autoconfig_16550a(struct uart_8250_port *up) serial_outp(up, UART_MCR, status1); if ((status2 ^ status1) & UART_MCR_LOOP) { -#ifndef CONFIG_PPC + unsigned short quot; + serial_outp(up, UART_LCR, 0xE0); + + quot = serial_inp(up, UART_DLM) << 8; + quot += serial_inp(up, UART_DLL); + quot <<= 3; + status1 = serial_in(up, 0x04); /* EXCR1 */ status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */ status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */ serial_outp(up, 0x04, status1); + + serial_outp(up, UART_DLL, quot & 0xff); + serial_outp(up, UART_DLM, quot >> 8); + serial_outp(up, UART_LCR, 0); - up->port.uartclk = 921600*16; -#endif + up->port.uartclk = 921600*16; up->port.type = PORT_NS16550A; up->capabilities |= UART_NATSEMI; return; -- cgit v1.2.2 From 1263cc67c09bc7f913a6877f3ba0427f0b76617e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 23 May 2005 10:03:52 +1000 Subject: [PATCH] ppc64: Fix booting on latest G5 models The latest speedbumped Apple G5 models have a "bug" in the Open Firmware device tree that lacks the proper interrupt routing information for the northbridge i2c controller. Apple's driver silently falls back into a sub-optimal "polled" mode (heh, maybe they didn't even notice the bug because of that :), our driver didn't properly check and crashes :( This patch fixes our driver to not crash, and adds code to the prom_init() OF trampoline code that detects the "bug" and adds the missing information back for this chipset revision. This fixes booting and thermal control on these models. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Linus Torvalds --- drivers/i2c/busses/i2c-keywest.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index dd0d4c463146..867d443e7133 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -516,6 +516,11 @@ create_iface(struct device_node *np, struct device *dev) u32 *psteps, *prate; int rc; + if (np->n_intrs < 1 || np->n_addrs < 1) { + printk(KERN_ERR "%s: Missing interrupt or address !\n", + np->full_name); + return -ENODEV; + } if (pmac_low_i2c_lock(np)) return -ENODEV; -- cgit v1.2.2 From d8659255c599ba497bcfb8b4abc187d9e0951d99 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Mon, 23 May 2005 12:54:51 -0700 Subject: [TG3]: Add 5752M device ID. Add 0x1601 as 5752M, it's a 5752 but for mobile PCs. Stolen from Broadcom bcm5700-8.1.55 driver. Someone forgot to add it to tg3 ;-) Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4d2bdbdd34e8..ebd882fbc705 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -206,6 +206,8 @@ static struct pci_device_id tg3_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5752M, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753M, -- cgit v1.2.2 From 413f5431a5a27e44c6610de640e507e1e3c885f4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 May 2005 13:13:15 -0700 Subject: [TG3]: Update driver version and reldate. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ebd882fbc705..fb168855b255 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -61,8 +61,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.27" -#define DRV_MODULE_RELDATE "May 5, 2005" +#define DRV_MODULE_VERSION "3.28" +#define DRV_MODULE_RELDATE "May 23, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.2.2 From ded7340d9d9142807a1ef94ab9c51d13ab76a1c9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 May 2005 13:59:47 -0700 Subject: [TG3]: Increase TEST_BUFFER_SIZE to 8K. This makes the DMA bug workaround test more likely to find the problem on some systems. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index fb168855b255..2bb022ab6682 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8996,7 +8996,7 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm return ret; } -#define TEST_BUFFER_SIZE 0x400 +#define TEST_BUFFER_SIZE 0x2000 static int __devinit tg3_test_dma(struct tg3 *tp) { -- cgit v1.2.2 From d1faeaeb95a05275cf0c5b51b88f2fa833434625 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 23 May 2005 14:00:44 -0700 Subject: [TG3]: Update driver version. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 2bb022ab6682..f10dd74988c4 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -61,7 +61,7 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.28" +#define DRV_MODULE_VERSION "3.29" #define DRV_MODULE_RELDATE "May 23, 2005" #define TG3_DEF_MAC_MODE 0 -- cgit v1.2.2 From 187a1a94d629621d1471b42308e63573b1150773 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 May 2005 15:50:26 -0700 Subject: [PATCH] driver core: restore event order for device_add() As a result of the split of the kobject-registration and the corresponding hotplug event, the order of events for device_add() has changed. This restores the old order, cause it confused some userspace applications. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/base/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index d21eb7744496..fbc223486f81 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -245,6 +245,7 @@ int device_add(struct device *dev) if ((error = kobject_add(&dev->kobj))) goto Error; + kobject_hotplug(&dev->kobj, KOBJ_ADD); if ((error = device_pm_add(dev))) goto PMError; if ((error = bus_add_device(dev))) @@ -257,14 +258,13 @@ int device_add(struct device *dev) /* notify platform of device entry */ if (platform_notify) platform_notify(dev); - - kobject_hotplug(&dev->kobj, KOBJ_ADD); Done: put_device(dev); return error; BusError: device_pm_remove(dev); PMError: + kobject_hotplug(&dev->kobj, KOBJ_REMOVE); kobject_del(&dev->kobj); Error: if (parent) -- cgit v1.2.2 From 9092f46b5aed4515d9a427d5dab3be1584851f07 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 18 May 2005 13:41:33 -0400 Subject: [PATCH] tulip: add return to ULI526X clause in tulip_mdio_write The 'if' clause for ULI526X in tulip_mdio_write allows for spin_unlock_irqrestore to be called twice for tp->mii_lock. I believe this is caused by the unintentional omission of a return at the end of that clause. This patch adds that return. Signed-off-by: John W. Linville --- drivers/net/tulip/media.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index edae09a4b021..919c40cd635c 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c @@ -174,6 +174,7 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int val) break; } spin_unlock_irqrestore(&tp->mii_lock, flags); + return; } /* Establish sync by sending 32 logic ones. */ -- cgit v1.2.2 From 558ac33e094f3a47c74a3a66b19cd3616f183184 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 24 May 2005 19:31:10 -0700 Subject: [PATCH] saa6752hs build fix For older gcc's. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/saa7134/saa6752hs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index fe6abe34168c..1db022682980 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c @@ -43,15 +43,15 @@ enum saa6752hs_videoformat { static const struct v4l2_format v4l2_format_table[] = { [SAA6752HS_VF_D1] = { - .fmt.pix.width = 720, .fmt.pix.height = 576 }, + .fmt = { .pix = { .width = 720, .height = 576 }, }, }, [SAA6752HS_VF_2_3_D1] = { - .fmt.pix.width = 480, .fmt.pix.height = 576 }, + .fmt = { .pix = { .width = 480, .height = 576 }, }, }, [SAA6752HS_VF_1_2_D1] = { - .fmt.pix.width = 352, .fmt.pix.height = 576 }, + .fmt = { .pix = { .width = 352, .height = 576 }, }, }, [SAA6752HS_VF_SIF] = { - .fmt.pix.width = 352, .fmt.pix.height = 288 }, + .fmt = { .pix = { .width = 352, .height = 288 }, }, }, [SAA6752HS_VF_UNKNOWN] = { - .fmt.pix.width = 0, .fmt.pix.height = 0}, + .fmt = { .pix = { .width = 0, .height = 0 }, }, }, }; struct saa6752hs_state { -- cgit v1.2.2 From d981289627a7e2d8ef62dfcaa11fb60da68f30c6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 24 May 2005 19:31:10 -0700 Subject: [PATCH] aic7xxx_osm build fix Fix a c99ism. Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index f90efa265ba2..c13e56320010 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -659,8 +659,11 @@ ahc_linux_slave_alloc(struct scsi_device *device) ahc_lock(ahc, &flags); targ = ahc->platform_data->targets[target_offset]; if (targ == NULL) { - targ = ahc_linux_alloc_target(ahc, starget->channel, starget->id); - struct seeprom_config *sc = ahc->seep_config; + struct seeprom_config *sc; + + targ = ahc_linux_alloc_target(ahc, starget->channel, + starget->id); + sc = ahc->seep_config; if (targ == NULL) goto out; -- cgit v1.2.2 From 0e15850200437c60b969025500e466383ec51ed8 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 25 May 2005 09:49:13 +0100 Subject: [PATCH] Speedtouch resync after lost signal. There's a bigger Speedtouch update coming your way after 2.6.12 but in the meantime, let's at least make it automatically resync if the DSL signal is lost. Signed-off-by: David Woodhouse Signed-off-by: Linus Torvalds --- drivers/usb/atm/speedtch.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 233f9229badb..2a1697bfd695 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -386,6 +386,8 @@ static void speedtch_poll_status(struct speedtch_instance_data *instance) if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) { instance->u.atm_dev->signal = ATM_PHY_SIG_LOST; printk(KERN_NOTICE "ADSL line is down\n"); + /* It'll never resync again unless we ask it to... */ + speedtch_start_synchro(instance); } break; -- cgit v1.2.2 From 384f1fcd2db8bc5a15f20f10793d8e1c82acd6c5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 25 May 2005 17:00:15 +0200 Subject: [PATCH] relax ide-cd dma restrictions This has been sitting for a while, and is causing lots of grief for people burning CDs. It relaxes the dma restriction for ide-cd, requiring only the length to be 32-byte aligned, address should be fine at normal double word alignment. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- drivers/ide/ide-cd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 33a020faeabd..4f7ce7056228 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1933,7 +1933,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) /* * check if dma is safe */ - if ((rq->data_len & mask) || (addr & mask)) + if ((rq->data_len & 3) || (addr & mask)) info->dma = 0; } -- cgit v1.2.2 From 5daf05fbf73fc199e7a93a818e504856d07c5586 Mon Sep 17 00:00:00 2001 From: Gerd Knorr Date: Wed, 25 May 2005 12:31:26 -0700 Subject: [PATCH] v4l: bttv i2c oops fix Don't try to access the i2c bus if the register wasn't successful. Signed-off-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/bttv-i2c.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index e3f477dff827..c2368bc832ed 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c @@ -363,6 +363,9 @@ int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, /* read EEPROM content */ void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr) { + memset(eedata, 0, 256); + if (0 != btv->i2c_rc) + return; btv->i2c_client.addr = addr >> 1; tveeprom_read(&btv->i2c_client, eedata, 256); } -- cgit v1.2.2 From dca79a046b93a81496bb30ca01177fb17f37ab72 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Wed, 25 May 2005 12:31:27 -0700 Subject: [PATCH] ipmi build fix It looks like the recent IPMI patches had some -mm-onlyisms. Signed-off-by: Neil Horman Cc: Corey Minyard Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_devintf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 4bb9af736fba..6dc765dc5413 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -520,7 +520,7 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By" " interface. Other values will set the major device number" " to that value."); -static struct class *ipmi_class; +static struct class_simple *ipmi_class; static void ipmi_new_smi(int if_num) { @@ -534,7 +534,7 @@ static void ipmi_new_smi(int if_num) static void ipmi_smi_gone(int if_num) { - class_simple_device_remove(ipmi_class, MKDEV(ipmi_major, if_num)); + class_simple_device_remove(MKDEV(ipmi_major, if_num)); devfs_remove("ipmidev/%d", if_num); } -- cgit v1.2.2 From e4f50f003dc568f6fc3904d451c562007bd09640 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 25 May 2005 12:31:29 -0700 Subject: [PATCH] IB: allow NULL sa_query callbacks Check if a client passes a NULL callback into an SA query, and if so, never call back. This fixes an oops if someone unloads ib_ipoib and ib_sa in rapid succession. ib_ipoib does an MCMember delete with a NULL callback and 0 timeout on unload, which is usually fine since the delete completes successfully. However, if ib_sa is unloaded immediately afterwards, the delete will be canceled and ib_sa will try to call the (now already unloaded) ib_ipoib module back with the cancel completion, which triggers the oops. Signed-off-by: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/core/sa_query.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index d4233ee61c35..276e1a53010d 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -587,7 +587,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, init_mad(query->sa_query.mad, agent); - query->sa_query.callback = ib_sa_path_rec_callback; + query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; query->sa_query.release = ib_sa_path_rec_release; query->sa_query.port = port; query->sa_query.mad->mad_hdr.method = IB_MGMT_METHOD_GET; @@ -663,7 +663,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, init_mad(query->sa_query.mad, agent); - query->sa_query.callback = ib_sa_mcmember_rec_callback; + query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; query->sa_query.release = ib_sa_mcmember_rec_release; query->sa_query.port = port; query->sa_query.mad->mad_hdr.method = method; @@ -698,20 +698,21 @@ static void send_handler(struct ib_mad_agent *agent, if (!query) return; - switch (mad_send_wc->status) { - case IB_WC_SUCCESS: - /* No callback -- already got recv */ - break; - case IB_WC_RESP_TIMEOUT_ERR: - query->callback(query, -ETIMEDOUT, NULL); - break; - case IB_WC_WR_FLUSH_ERR: - query->callback(query, -EINTR, NULL); - break; - default: - query->callback(query, -EIO, NULL); - break; - } + if (query->callback) + switch (mad_send_wc->status) { + case IB_WC_SUCCESS: + /* No callback -- already got recv */ + break; + case IB_WC_RESP_TIMEOUT_ERR: + query->callback(query, -ETIMEDOUT, NULL); + break; + case IB_WC_WR_FLUSH_ERR: + query->callback(query, -EINTR, NULL); + break; + default: + query->callback(query, -EIO, NULL); + break; + } dma_unmap_single(agent->device->dma_device, pci_unmap_addr(query, mapping), @@ -736,7 +737,7 @@ static void recv_handler(struct ib_mad_agent *mad_agent, query = idr_find(&query_idr, mad_recv_wc->wc->wr_id); spin_unlock_irqrestore(&idr_lock, flags); - if (query) { + if (query && query->callback) { if (mad_recv_wc->wc->status == IB_WC_SUCCESS) query->callback(query, mad_recv_wc->recv_buf.mad->mad_hdr.status ? -- cgit v1.2.2 From 561e148ea972a6e8d2c8f7aecc658b3a64f7a6de Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 25 May 2005 12:31:30 -0700 Subject: [PATCH] IB: fix potential ib_umad leak Free all unclaimed MAD receive buffers when userspace closes our file so we don't leak memory. Signed-off-by: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/core/user_mad.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 56b9c2fa2ecc..9d912d6877ff 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -499,6 +499,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) static int ib_umad_close(struct inode *inode, struct file *filp) { struct ib_umad_file *file = filp->private_data; + struct ib_umad_packet *packet, *tmp; int i; for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) @@ -507,6 +508,9 @@ static int ib_umad_close(struct inode *inode, struct file *filp) ib_unregister_mad_agent(file->agent[i]); } + list_for_each_entry_safe(packet, tmp, &file->recv_list, list) + kfree(packet); + kfree(file); return 0; -- cgit v1.2.2 From 3bf4fb820d7382318d178bd765c20028415466ab Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Wed, 25 May 2005 12:31:31 -0700 Subject: [PATCH] IB: fix endianness of path record MTU field Make MTU field in SA PathRecord and MCMemberRecord a u8 rather than an enum to avoid complications with endianness. Signed-off-by: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/include/ib_sa.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/include/ib_sa.h b/drivers/infiniband/include/ib_sa.h index f4f747707b30..00222285eb9a 100644 --- a/drivers/infiniband/include/ib_sa.h +++ b/drivers/infiniband/include/ib_sa.h @@ -147,7 +147,7 @@ struct ib_sa_path_rec { /* reserved */ u8 sl; u8 mtu_selector; - enum ib_mtu mtu; + u8 mtu; u8 rate_selector; u8 rate; u8 packet_life_time_selector; @@ -180,7 +180,7 @@ struct ib_sa_mcmember_rec { u32 qkey; u16 mlid; u8 mtu_selector; - enum ib_mtu mtu; + u8 mtu; u8 traffic_class; u16 pkey; u8 rate_selector; -- cgit v1.2.2 From a8bacec09352b86bd389cc93a20008577fa14764 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Wed, 25 May 2005 12:31:34 -0700 Subject: [PATCH] Make sure therm_adt746x only handles known hardware This patch limits therm_adt746x to currently existing fan controllers in Apple laptops. It may avoid problems with future hardware. Signed-off-by: Colin Leroy Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/therm_adt746x.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index e0ac63effa55..c7e84abe8951 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -545,6 +545,12 @@ thermostat_init(void) else return -ENODEV; + prop = (u32 *)get_property(np, "hwsensor-params-version", NULL); + printk(KERN_INFO "adt746x: version %d (%ssupported)\n", *prop, + (*prop == 1)?"":"un"); + if (*prop != 1) + return -ENODEV; + prop = (u32 *)get_property(np, "reg", NULL); if (!prop) return -ENODEV; -- cgit v1.2.2 From d20c507f28dbee33086e8212b98f9ddc5372cd81 Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Wed, 25 May 2005 12:31:35 -0700 Subject: [PATCH] therm_adt746x: show correct sensor locations This patch shows the correct locations of the heat sensors present in iBook and PowerBooks G4, instead of displaying them as being on CPU and GPU (which is not always the case). Signed-off-by: Colin Leroy Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/therm_adt746x.c | 119 ++++++++++++++++++++++++-------------- 1 file changed, 77 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index c7e84abe8951..d09308f30960 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -39,15 +39,16 @@ #define MANUAL_MASK 0xe0 #define AUTO_MASK 0x20 -static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, cpu, gpu */ -static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, cpu, gpu */ +static u8 TEMP_REG[3] = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */ +static u8 LIMIT_REG[3] = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */ static u8 MANUAL_MODE[2] = {0x5c, 0x5d}; static u8 REM_CONTROL[2] = {0x00, 0x40}; static u8 FAN_SPEED[2] = {0x28, 0x2a}; static u8 FAN_SPD_SET[2] = {0x30, 0x31}; -static u8 default_limits_local[3] = {70, 50, 70}; /* local, cpu, gpu */ -static u8 default_limits_chip[3] = {80, 65, 80}; /* local, cpu, gpu */ +static u8 default_limits_local[3] = {70, 50, 70}; /* local, sensor1, sensor2 */ +static u8 default_limits_chip[3] = {80, 65, 80}; /* local, sensor1, sensor2 */ +static char *sensor_location[3] = {NULL, NULL, NULL}; static int limit_adjust = 0; static int fan_speed = -1; @@ -58,7 +59,7 @@ MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and " MODULE_LICENSE("GPL"); module_param(limit_adjust, int, 0644); -MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 cpu, 70 gpu) " +MODULE_PARM_DESC(limit_adjust,"Adjust maximum temperatures (50 sensor1, 70 sensor2) " "by N degrees."); module_param(fan_speed, int, 0644); @@ -213,10 +214,10 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan) if (th->last_speed[fan] != speed) { if (speed == -1) printk(KERN_DEBUG "adt746x: Setting speed to automatic " - "for %s fan.\n", fan?"GPU":"CPU"); + "for %s fan.\n", sensor_location[fan+1]); else printk(KERN_DEBUG "adt746x: Setting speed to %d " - "for %s fan.\n", speed, fan?"GPU":"CPU"); + "for %s fan.\n", speed, sensor_location[fan+1]); } else return; @@ -300,11 +301,11 @@ static void update_fans_speed (struct thermostat *th) printk(KERN_DEBUG "adt746x: setting fans speed to %d " "(limit exceeded by %d on %s) \n", new_speed, var, - fan_number?"GPU/pwr":"CPU"); + sensor_location[fan_number+1]); write_both_fan_speed(th, new_speed); th->last_var[fan_number] = var; } else if (var < -2) { - /* don't stop fan if GPU/power is cold and CPU is not + /* don't stop fan if sensor2 is cold and sensor1 is not * so cold (lastvar >= -1) */ if (i == 2 && lastvar < -1) { if (th->last_speed[fan_number] != 0) @@ -318,7 +319,7 @@ static void update_fans_speed (struct thermostat *th) if (started) return; /* we don't want to re-stop the fan - * if CPU is heating and GPU/power is not */ + * if sensor1 is heating and sensor2 is not */ } } @@ -353,7 +354,7 @@ static int monitor_task(void *arg) static void set_limit(struct thermostat *th, int i) { - /* Set CPU limit higher to avoid powerdowns */ + /* Set sensor1 limit higher to avoid powerdowns */ th->limits[i] = default_limits_chip[i] + limit_adjust; write_reg(th, LIMIT_REG[i], th->limits[i]); @@ -461,6 +462,12 @@ static ssize_t show_##name(struct device *dev, char *buf) \ return sprintf(buf, "%d\n", data); \ } +#define BUILD_SHOW_FUNC_STR(name, data) \ +static ssize_t show_##name(struct device *dev, char *buf) \ +{ \ + return sprintf(buf, "%s\n", data); \ +} + #define BUILD_SHOW_FUNC_FAN(name, data) \ static ssize_t show_##name(struct device *dev, char *buf) \ { \ @@ -476,7 +483,7 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \ int val; \ int i; \ val = simple_strtol(buf, NULL, 10); \ - printk(KERN_INFO "Adjusting limits by %d°C\n", val); \ + printk(KERN_INFO "Adjusting limits by %d degrees\n", val); \ limit_adjust = val; \ for (i=0; i < 3; i++) \ set_limit(thermostat, i); \ @@ -495,35 +502,41 @@ static ssize_t store_##name(struct device *dev, const char *buf, size_t n) \ return n; \ } -BUILD_SHOW_FUNC_INT(cpu_temperature, (read_reg(thermostat, TEMP_REG[1]))) -BUILD_SHOW_FUNC_INT(gpu_temperature, (read_reg(thermostat, TEMP_REG[2]))) -BUILD_SHOW_FUNC_INT(cpu_limit, thermostat->limits[1]) -BUILD_SHOW_FUNC_INT(gpu_limit, thermostat->limits[2]) +BUILD_SHOW_FUNC_INT(sensor1_temperature, (read_reg(thermostat, TEMP_REG[1]))) +BUILD_SHOW_FUNC_INT(sensor2_temperature, (read_reg(thermostat, TEMP_REG[2]))) +BUILD_SHOW_FUNC_INT(sensor1_limit, thermostat->limits[1]) +BUILD_SHOW_FUNC_INT(sensor2_limit, thermostat->limits[2]) +BUILD_SHOW_FUNC_STR(sensor1_location, sensor_location[1]) +BUILD_SHOW_FUNC_STR(sensor2_location, sensor_location[2]) BUILD_SHOW_FUNC_INT(specified_fan_speed, fan_speed) -BUILD_SHOW_FUNC_FAN(cpu_fan_speed, 0) -BUILD_SHOW_FUNC_FAN(gpu_fan_speed, 1) +BUILD_SHOW_FUNC_FAN(sensor1_fan_speed, 0) +BUILD_SHOW_FUNC_FAN(sensor2_fan_speed, 1) BUILD_STORE_FUNC_INT(specified_fan_speed,fan_speed) BUILD_SHOW_FUNC_INT(limit_adjust, limit_adjust) BUILD_STORE_FUNC_DEG(limit_adjust, thermostat) -static DEVICE_ATTR(cpu_temperature, S_IRUGO, - show_cpu_temperature,NULL); -static DEVICE_ATTR(gpu_temperature, S_IRUGO, - show_gpu_temperature,NULL); -static DEVICE_ATTR(cpu_limit, S_IRUGO, - show_cpu_limit, NULL); -static DEVICE_ATTR(gpu_limit, S_IRUGO, - show_gpu_limit, NULL); +static DEVICE_ATTR(sensor1_temperature, S_IRUGO, + show_sensor1_temperature,NULL); +static DEVICE_ATTR(sensor2_temperature, S_IRUGO, + show_sensor2_temperature,NULL); +static DEVICE_ATTR(sensor1_limit, S_IRUGO, + show_sensor1_limit, NULL); +static DEVICE_ATTR(sensor2_limit, S_IRUGO, + show_sensor2_limit, NULL); +static DEVICE_ATTR(sensor1_location, S_IRUGO, + show_sensor1_location, NULL); +static DEVICE_ATTR(sensor2_location, S_IRUGO, + show_sensor2_location, NULL); static DEVICE_ATTR(specified_fan_speed, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, show_specified_fan_speed,store_specified_fan_speed); -static DEVICE_ATTR(cpu_fan_speed, S_IRUGO, - show_cpu_fan_speed, NULL); -static DEVICE_ATTR(gpu_fan_speed, S_IRUGO, - show_gpu_fan_speed, NULL); +static DEVICE_ATTR(sensor1_fan_speed, S_IRUGO, + show_sensor1_fan_speed, NULL); +static DEVICE_ATTR(sensor2_fan_speed, S_IRUGO, + show_sensor2_fan_speed, NULL); static DEVICE_ATTR(limit_adjust, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, show_limit_adjust, store_limit_adjust); @@ -534,6 +547,7 @@ thermostat_init(void) { struct device_node* np; u32 *prop; + int i = 0, offset = 0; np = of_find_node_by_name(NULL, "fan"); if (!np) @@ -569,6 +583,23 @@ thermostat_init(void) "limit_adjust: %d, fan_speed: %d\n", therm_bus, therm_address, limit_adjust, fan_speed); + if (get_property(np, "hwsensor-location", NULL)) { + for (i = 0; i < 3; i++) { + sensor_location[i] = get_property(np, + "hwsensor-location", NULL) + offset; + + if (sensor_location[i] == NULL) + sensor_location[i] = ""; + + printk(KERN_INFO "sensor %d: %s\n", i, sensor_location[i]); + offset += strlen(sensor_location[i]) + 1; + } + } else { + sensor_location[0] = "?"; + sensor_location[1] = "?"; + sensor_location[2] = "?"; + } + of_dev = of_platform_device_create(np, "temperatures"); if (of_dev == NULL) { @@ -576,15 +607,17 @@ thermostat_init(void) return -ENODEV; } - device_create_file(&of_dev->dev, &dev_attr_cpu_temperature); - device_create_file(&of_dev->dev, &dev_attr_gpu_temperature); - device_create_file(&of_dev->dev, &dev_attr_cpu_limit); - device_create_file(&of_dev->dev, &dev_attr_gpu_limit); + device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); + device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); + device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); + device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); + device_create_file(&of_dev->dev, &dev_attr_sensor1_location); + device_create_file(&of_dev->dev, &dev_attr_sensor2_location); device_create_file(&of_dev->dev, &dev_attr_limit_adjust); device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); - device_create_file(&of_dev->dev, &dev_attr_cpu_fan_speed); + device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); if(therm_type == ADT7460) - device_create_file(&of_dev->dev, &dev_attr_gpu_fan_speed); + device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); #ifndef CONFIG_I2C_KEYWEST request_module("i2c-keywest"); @@ -597,17 +630,19 @@ static void __exit thermostat_exit(void) { if (of_dev) { - device_remove_file(&of_dev->dev, &dev_attr_cpu_temperature); - device_remove_file(&of_dev->dev, &dev_attr_gpu_temperature); - device_remove_file(&of_dev->dev, &dev_attr_cpu_limit); - device_remove_file(&of_dev->dev, &dev_attr_gpu_limit); + device_remove_file(&of_dev->dev, &dev_attr_sensor1_temperature); + device_remove_file(&of_dev->dev, &dev_attr_sensor2_temperature); + device_remove_file(&of_dev->dev, &dev_attr_sensor1_limit); + device_remove_file(&of_dev->dev, &dev_attr_sensor2_limit); + device_remove_file(&of_dev->dev, &dev_attr_sensor1_location); + device_remove_file(&of_dev->dev, &dev_attr_sensor2_location); device_remove_file(&of_dev->dev, &dev_attr_limit_adjust); device_remove_file(&of_dev->dev, &dev_attr_specified_fan_speed); - device_remove_file(&of_dev->dev, &dev_attr_cpu_fan_speed); + device_remove_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); if(therm_type == ADT7460) device_remove_file(&of_dev->dev, - &dev_attr_gpu_fan_speed); + &dev_attr_sensor2_fan_speed); of_device_unregister(of_dev); } -- cgit v1.2.2 From 525a099771d348a25d12ef9c47aa8680c7317e35 Mon Sep 17 00:00:00 2001 From: NAKAMURA Kenta Date: Wed, 25 May 2005 19:28:38 -0400 Subject: [PATCH] sata_sil: new ID 1002:437A for ATI IXP400 --- drivers/scsi/sata_sil.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index f0489dc302a0..2b2ff48be396 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -82,6 +82,7 @@ static struct pci_device_id sil_pci_tbl[] = { { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, + { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, { } /* terminate list */ }; -- cgit v1.2.2 From 4c3a53d4108367f639e5e0fe9366dfd7679c5514 Mon Sep 17 00:00:00 2001 From: Francisco Javier Date: Wed, 25 May 2005 19:29:37 -0400 Subject: [PATCH] sata_promise: add PCI ID for FastTrak TX2200 2-ports --- drivers/scsi/sata_promise.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 19a13e3590f4..c4e9e0298122 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -151,6 +151,8 @@ static struct ata_port_info pdc_port_info[] = { static struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, + { PCI_VENDOR_ID_PROMISE, 0x3571, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3373, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_2037x }, { PCI_VENDOR_ID_PROMISE, 0x3375, PCI_ANY_ID, PCI_ANY_ID, 0, 0, -- cgit v1.2.2 From 32529e0128923e42126b5d14e444c18295a452ba Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Thu, 26 May 2005 03:49:42 -0400 Subject: [PATCH] libata: Fix zero sg_dma_len() on 64-bit platform When testing ATAPI PIO data transfer on the ppc64 platform, __atapi_pio_bytes() got zero when sg_dma_len() is used. I checked the , the struct scatterlist is defined as: struct scatterlist { struct page *page; unsigned int offset; unsigned int length; /* For TCE support */ u32 dma_address; u32 dma_length; }; #define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->dma_length) So, if the scatterlist is not DMA mapped, sg_dma_len() will return zero on ppc64. The same problem should occur on the x86-64 platform. On the i386 platform, sg_dma_len() returns sg->length, that's why the problem does not occur on an i386. Changes: - Use sg->length if the scatterlist is not DMA mapped (yet). Signed-off-by: Albert Lee --- drivers/scsi/libata-core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index ee9b96da841e..63d3f70d06e1 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -2071,7 +2071,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) sg = qc->sg; sg->page = virt_to_page(buf); sg->offset = (unsigned long) buf & ~PAGE_MASK; - sg_dma_len(sg) = buflen; + sg->length = buflen; } void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, @@ -2101,11 +2101,12 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) dma_addr_t dma_address; dma_address = dma_map_single(ap->host_set->dev, qc->buf_virt, - sg_dma_len(sg), dir); + sg->length, dir); if (dma_mapping_error(dma_address)) return -1; sg_dma_address(sg) = dma_address; + sg_dma_len(sg) = sg->length; DPRINTK("mapped buffer of %d bytes for %s\n", sg_dma_len(sg), qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read"); @@ -2310,7 +2311,7 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) qc->cursect++; qc->cursg_ofs++; - if ((qc->cursg_ofs * ATA_SECT_SIZE) == sg_dma_len(&sg[qc->cursg])) { + if ((qc->cursg_ofs * ATA_SECT_SIZE) == (&sg[qc->cursg])->length) { qc->cursg++; qc->cursg_ofs = 0; } @@ -2347,7 +2348,7 @@ next_page: page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; - count = min(sg_dma_len(sg) - qc->cursg_ofs, bytes); + count = min(sg->length - qc->cursg_ofs, bytes); /* don't cross page boundaries */ count = min(count, (unsigned int)PAGE_SIZE - offset); @@ -2358,7 +2359,7 @@ next_page: qc->curbytes += count; qc->cursg_ofs += count; - if (qc->cursg_ofs == sg_dma_len(sg)) { + if (qc->cursg_ofs == sg->length) { qc->cursg++; qc->cursg_ofs = 0; } @@ -2371,7 +2372,7 @@ next_page: kunmap(page); if (bytes) { - if (qc->cursg_ofs < sg_dma_len(sg)) + if (qc->cursg_ofs < sg->length) goto next_page; goto next_sg; } -- cgit v1.2.2 From 8604affde9d4f52f04342d6a37c77d95fa167e7a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 26 May 2005 14:55:34 +0200 Subject: [PATCH] convert IDE device drivers to driver-model * add ide_bus_match() and export ide_bus_type * split ide_remove_driver_from_hwgroup() out of ide_unregister() * move device cleanup from ide_unregister() to drive_release_dev() * convert ide_driver_t->name to driver->name * convert ide_driver_t->{attach,cleanup} to driver->{probe,remove} * remove ide_driver_t->busy as ide_bus_type->subsys.rwsem protects against concurrent ->{probe,remove} calls * make ide_{un}register_driver() void as it cannot fail now * use driver_{un}register() directly, remove ide_{un}register_driver() * use device_register() instead of ata_attach(), remove ata_attach() * add proc_print_driver() and ide_drivers_show(), remove ide_drivers_op * fix ide_replace_subdriver() and move it to ide-proc.c * remove ide_driver_t->drives, ide_drives and drives_lock * remove ide_driver_t->drivers, drivers and drivers_lock * remove ide_drive_t->driver and DRIVER() macro Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-cd.c | 47 +++----- drivers/ide/ide-disk.c | 41 +++---- drivers/ide/ide-floppy.c | 42 +++---- drivers/ide/ide-probe.c | 47 +++++++- drivers/ide/ide-proc.c | 52 +++++++- drivers/ide/ide-tape.c | 51 +++----- drivers/ide/ide.c | 307 ++++------------------------------------------- drivers/scsi/ide-scsi.c | 58 ++++----- 8 files changed, 212 insertions(+), 433 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4f7ce7056228..f0bd242e030f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -3255,16 +3255,12 @@ sector_t ide_cdrom_capacity (ide_drive_t *drive) return capacity * sectors_per_frame; } -static -int ide_cdrom_cleanup(ide_drive_t *drive) +static int ide_cd_remove(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); struct cdrom_info *info = drive->driver_data; - if (ide_unregister_subdriver(drive)) { - printk(KERN_ERR "%s: %s: failed to ide_unregister_subdriver\n", - __FUNCTION__, drive->name); - return 1; - } + ide_unregister_subdriver(drive, info->driver); del_gendisk(info->disk); @@ -3297,7 +3293,7 @@ static void ide_cd_release(struct kref *kref) kfree(info); } -static int ide_cdrom_attach (ide_drive_t *drive); +static int ide_cd_probe(struct device *); #ifdef CONFIG_PROC_FS static int proc_idecd_read_capacity @@ -3320,19 +3316,20 @@ static ide_proc_entry_t idecd_proc[] = { static ide_driver_t ide_cdrom_driver = { .owner = THIS_MODULE, - .name = "ide-cdrom", + .gen_driver = { + .name = "ide-cdrom", + .bus = &ide_bus_type, + .probe = ide_cd_probe, + .remove = ide_cd_remove, + }, .version = IDECD_VERSION, .media = ide_cdrom, - .busy = 0, .supports_dsc_overlap = 1, - .cleanup = ide_cdrom_cleanup, .do_request = ide_do_rw_cdrom, .end_request = ide_end_request, .error = __ide_error, .abort = __ide_abort, .proc = idecd_proc, - .attach = ide_cdrom_attach, - .drives = LIST_HEAD_INIT(ide_cdrom_driver.drives), }; static int idecd_open(struct inode * inode, struct file * file) @@ -3418,8 +3415,9 @@ static char *ignore = NULL; module_param(ignore, charp, 0400); MODULE_DESCRIPTION("ATAPI CD-ROM Driver"); -static int ide_cdrom_attach (ide_drive_t *drive) +static int ide_cd_probe(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); struct cdrom_info *info; struct gendisk *g; struct request_sense sense; @@ -3453,11 +3451,8 @@ static int ide_cdrom_attach (ide_drive_t *drive) ide_init_disk(g, drive); - if (ide_register_subdriver(drive, &ide_cdrom_driver)) { - printk(KERN_ERR "%s: Failed to register the driver with ide.c\n", - drive->name); - goto out_put_disk; - } + ide_register_subdriver(drive, &ide_cdrom_driver); + memset(info, 0, sizeof (struct cdrom_info)); kref_init(&info->kref); @@ -3470,7 +3465,6 @@ static int ide_cdrom_attach (ide_drive_t *drive) drive->driver_data = info; - DRIVER(drive)->busy++; g->minors = 1; snprintf(g->devfs_name, sizeof(g->devfs_name), "%s/cd", drive->devfs_name); @@ -3478,8 +3472,7 @@ static int ide_cdrom_attach (ide_drive_t *drive) g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE; if (ide_cdrom_setup(drive)) { struct cdrom_device_info *devinfo = &info->devinfo; - DRIVER(drive)->busy--; - ide_unregister_subdriver(drive); + ide_unregister_subdriver(drive, &ide_cdrom_driver); if (info->buffer != NULL) kfree(info->buffer); if (info->toc != NULL) @@ -3492,7 +3485,6 @@ static int ide_cdrom_attach (ide_drive_t *drive) drive->driver_data = NULL; goto failed; } - DRIVER(drive)->busy--; cdrom_read_toc(drive, &sense); g->fops = &idecd_ops; @@ -3500,23 +3492,20 @@ static int ide_cdrom_attach (ide_drive_t *drive) add_disk(g); return 0; -out_put_disk: - put_disk(g); out_free_cd: kfree(info); failed: - return 1; + return -ENODEV; } static void __exit ide_cdrom_exit(void) { - ide_unregister_driver(&ide_cdrom_driver); + driver_unregister(&ide_cdrom_driver.gen_driver); } static int ide_cdrom_init(void) { - ide_register_driver(&ide_cdrom_driver); - return 0; + return driver_register(&ide_cdrom_driver.gen_driver); } module_init(ide_cdrom_init); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5d54f7756100..3302cd8eab4c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -1024,14 +1024,16 @@ static void ide_cacheflush_p(ide_drive_t *drive) printk(KERN_INFO "%s: wcache flush failed!\n", drive->name); } -static int idedisk_cleanup (ide_drive_t *drive) +static int ide_disk_remove(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); struct ide_disk_obj *idkp = drive->driver_data; struct gendisk *g = idkp->disk; ide_cacheflush_p(drive); - if (ide_unregister_subdriver(drive)) - return 1; + + ide_unregister_subdriver(drive, idkp->driver); + del_gendisk(g); ide_disk_put(idkp); @@ -1052,7 +1054,7 @@ static void ide_disk_release(struct kref *kref) kfree(idkp); } -static int idedisk_attach(ide_drive_t *drive); +static int ide_disk_probe(struct device *dev); static void ide_device_shutdown(struct device *dev) { @@ -1082,27 +1084,23 @@ static void ide_device_shutdown(struct device *dev) dev->bus->suspend(dev, PMSG_SUSPEND); } -/* - * IDE subdriver functions, registered with ide.c - */ static ide_driver_t idedisk_driver = { .owner = THIS_MODULE, .gen_driver = { + .name = "ide-disk", + .bus = &ide_bus_type, + .probe = ide_disk_probe, + .remove = ide_disk_remove, .shutdown = ide_device_shutdown, }, - .name = "ide-disk", .version = IDEDISK_VERSION, .media = ide_disk, - .busy = 0, .supports_dsc_overlap = 0, - .cleanup = idedisk_cleanup, .do_request = ide_do_rw_disk, .end_request = ide_end_request, .error = __ide_error, .abort = __ide_abort, .proc = idedisk_proc, - .attach = idedisk_attach, - .drives = LIST_HEAD_INIT(idedisk_driver.drives), }; static int idedisk_open(struct inode *inode, struct file *filp) @@ -1199,8 +1197,9 @@ static struct block_device_operations idedisk_ops = { MODULE_DESCRIPTION("ATA DISK Driver"); -static int idedisk_attach(ide_drive_t *drive) +static int ide_disk_probe(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); struct ide_disk_obj *idkp; struct gendisk *g; @@ -1222,10 +1221,7 @@ static int idedisk_attach(ide_drive_t *drive) ide_init_disk(g, drive); - if (ide_register_subdriver(drive, &idedisk_driver)) { - printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name); - goto out_put_disk; - } + ide_register_subdriver(drive, &idedisk_driver); memset(idkp, 0, sizeof(*idkp)); @@ -1239,7 +1235,6 @@ static int idedisk_attach(ide_drive_t *drive) drive->driver_data = idkp; - DRIVER(drive)->busy++; idedisk_setup(drive); if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", @@ -1247,7 +1242,7 @@ static int idedisk_attach(ide_drive_t *drive) drive->attach = 0; } else drive->attach = 1; - DRIVER(drive)->busy--; + g->minors = 1 << PARTN_BITS; strcpy(g->devfs_name, drive->devfs_name); g->driverfs_dev = &drive->gendev; @@ -1257,22 +1252,20 @@ static int idedisk_attach(ide_drive_t *drive) add_disk(g); return 0; -out_put_disk: - put_disk(g); out_free_idkp: kfree(idkp); failed: - return 1; + return -ENODEV; } static void __exit idedisk_exit (void) { - ide_unregister_driver(&idedisk_driver); + driver_unregister(&idedisk_driver.gen_driver); } static int idedisk_init (void) { - return ide_register_driver(&idedisk_driver); + return driver_register(&idedisk_driver.gen_driver); } module_init(idedisk_init); diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 36c0b74a4e45..c949e98df4b6 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -1865,13 +1865,13 @@ static void idefloppy_setup (ide_drive_t *drive, idefloppy_floppy_t *floppy) idefloppy_add_settings(drive); } -static int idefloppy_cleanup (ide_drive_t *drive) +static int ide_floppy_remove(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); idefloppy_floppy_t *floppy = drive->driver_data; struct gendisk *g = floppy->disk; - if (ide_unregister_subdriver(drive)) - return 1; + ide_unregister_subdriver(drive, floppy->driver); del_gendisk(g); @@ -1916,26 +1916,24 @@ static ide_proc_entry_t idefloppy_proc[] = { #endif /* CONFIG_PROC_FS */ -static int idefloppy_attach(ide_drive_t *drive); +static int ide_floppy_probe(struct device *); -/* - * IDE subdriver functions, registered with ide.c - */ static ide_driver_t idefloppy_driver = { .owner = THIS_MODULE, - .name = "ide-floppy", + .gen_driver = { + .name = "ide-floppy", + .bus = &ide_bus_type, + .probe = ide_floppy_probe, + .remove = ide_floppy_remove, + }, .version = IDEFLOPPY_VERSION, .media = ide_floppy, - .busy = 0, .supports_dsc_overlap = 0, - .cleanup = idefloppy_cleanup, .do_request = idefloppy_do_request, .end_request = idefloppy_do_end_request, .error = __ide_error, .abort = __ide_abort, .proc = idefloppy_proc, - .attach = idefloppy_attach, - .drives = LIST_HEAD_INIT(idefloppy_driver.drives), }; static int idefloppy_open(struct inode *inode, struct file *filp) @@ -2122,8 +2120,9 @@ static struct block_device_operations idefloppy_ops = { .revalidate_disk= idefloppy_revalidate_disk }; -static int idefloppy_attach (ide_drive_t *drive) +static int ide_floppy_probe(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); idefloppy_floppy_t *floppy; struct gendisk *g; @@ -2152,10 +2151,7 @@ static int idefloppy_attach (ide_drive_t *drive) ide_init_disk(g, drive); - if (ide_register_subdriver(drive, &idefloppy_driver)) { - printk (KERN_ERR "ide-floppy: %s: Failed to register the driver with ide.c\n", drive->name); - goto out_put_disk; - } + ide_register_subdriver(drive, &idefloppy_driver); memset(floppy, 0, sizeof(*floppy)); @@ -2169,9 +2165,8 @@ static int idefloppy_attach (ide_drive_t *drive) drive->driver_data = floppy; - DRIVER(drive)->busy++; idefloppy_setup (drive, floppy); - DRIVER(drive)->busy--; + g->minors = 1 << PARTN_BITS; g->driverfs_dev = &drive->gendev; strcpy(g->devfs_name, drive->devfs_name); @@ -2181,19 +2176,17 @@ static int idefloppy_attach (ide_drive_t *drive) add_disk(g); return 0; -out_put_disk: - put_disk(g); out_free_floppy: kfree(floppy); failed: - return 1; + return -ENODEV; } MODULE_DESCRIPTION("ATAPI FLOPPY Driver"); static void __exit idefloppy_exit (void) { - ide_unregister_driver(&idefloppy_driver); + driver_unregister(&idefloppy_driver.gen_driver); } /* @@ -2202,8 +2195,7 @@ static void __exit idefloppy_exit (void) static int idefloppy_init (void) { printk("ide-floppy driver " IDEFLOPPY_VERSION "\n"); - ide_register_driver(&idefloppy_driver); - return 0; + return driver_register(&idefloppy_driver.gen_driver); } module_init(idefloppy_init); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 554473a95cf7..53b84a84f6cb 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -918,7 +919,7 @@ int probe_hwif_init_with_fixup(ide_hwif_t *hwif, void (*fixup)(ide_hwif_t *hwif) want them on default or a new "empty" class for hotplug reprobing ? */ if (drive->present) { - ata_attach(drive); + device_register(&drive->gendev); } } } @@ -1279,10 +1280,51 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) EXPORT_SYMBOL_GPL(ide_init_disk); +static void ide_remove_drive_from_hwgroup(ide_drive_t *drive) +{ + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; + + if (drive == drive->next) { + /* special case: last drive from hwgroup. */ + BUG_ON(hwgroup->drive != drive); + hwgroup->drive = NULL; + } else { + ide_drive_t *walk; + + walk = hwgroup->drive; + while (walk->next != drive) + walk = walk->next; + walk->next = drive->next; + if (hwgroup->drive == drive) { + hwgroup->drive = drive->next; + hwgroup->hwif = hwgroup->drive->hwif; + } + } + BUG_ON(hwgroup->drive == drive); +} + static void drive_release_dev (struct device *dev) { ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); + spin_lock_irq(&ide_lock); + if (drive->devfs_name[0] != '\0') { + devfs_remove(drive->devfs_name); + drive->devfs_name[0] = '\0'; + } + ide_remove_drive_from_hwgroup(drive); + if (drive->id != NULL) { + kfree(drive->id); + drive->id = NULL; + } + drive->present = 0; + /* Messed up locking ... */ + spin_unlock_irq(&ide_lock); + blk_cleanup_queue(drive->queue); + spin_lock_irq(&ide_lock); + drive->queue = NULL; + spin_unlock_irq(&ide_lock); + up(&drive->gendev_rel_sem); } @@ -1306,7 +1348,6 @@ static void init_gendisk (ide_hwif_t *hwif) drive->gendev.driver_data = drive; drive->gendev.release = drive_release_dev; if (drive->present) { - device_register(&drive->gendev); sprintf(drive->devfs_name, "ide/host%d/bus%d/target%d/lun%d", (hwif->channel && hwif->mate) ? hwif->mate->index : hwif->index, @@ -1412,7 +1453,7 @@ int ideprobe_init (void) hwif->chipset = ide_generic; for (unit = 0; unit < MAX_DRIVES; ++unit) if (hwif->drives[unit].present) - ata_attach(&hwif->drives[unit]); + device_register(&hwif->drives[unit].gendev); } } return 0; diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 4b1e43b4118b..4063d2c34e3d 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c @@ -307,17 +307,41 @@ static int proc_ide_read_driver (char *page, char **start, off_t off, int count, int *eof, void *data) { ide_drive_t *drive = (ide_drive_t *) data; - ide_driver_t *driver = drive->driver; + struct device *dev = &drive->gendev; + ide_driver_t *ide_drv; int len; - if (driver) { + down_read(&dev->bus->subsys.rwsem); + if (dev->driver) { + ide_drv = container_of(dev->driver, ide_driver_t, gen_driver); len = sprintf(page, "%s version %s\n", - driver->name, driver->version); + dev->driver->name, ide_drv->version); } else len = sprintf(page, "ide-default version 0.9.newide\n"); + up_read(&dev->bus->subsys.rwsem); PROC_IDE_READ_RETURN(page,start,off,count,eof,len); } +static int ide_replace_subdriver(ide_drive_t *drive, const char *driver) +{ + struct device *dev = &drive->gendev; + int ret = 1; + + down_write(&dev->bus->subsys.rwsem); + device_release_driver(dev); + /* FIXME: device can still be in use by previous driver */ + strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); + device_attach(dev); + drive->driver_req[0] = 0; + if (dev->driver == NULL) + device_attach(dev); + if (dev->driver && !strcmp(dev->driver->name, driver)) + ret = 0; + up_write(&dev->bus->subsys.rwsem); + + return ret; +} + static int proc_ide_write_driver (struct file *file, const char __user *buffer, unsigned long count, void *data) { @@ -488,16 +512,32 @@ void destroy_proc_ide_interface(ide_hwif_t *hwif) } } -extern struct seq_operations ide_drivers_op; +static int proc_print_driver(struct device_driver *drv, void *data) +{ + ide_driver_t *ide_drv = container_of(drv, ide_driver_t, gen_driver); + struct seq_file *s = data; + + seq_printf(s, "%s version %s\n", drv->name, ide_drv->version); + + return 0; +} + +static int ide_drivers_show(struct seq_file *s, void *p) +{ + bus_for_each_drv(&ide_bus_type, NULL, s, proc_print_driver); + return 0; +} + static int ide_drivers_open(struct inode *inode, struct file *file) { - return seq_open(file, &ide_drivers_op); + return single_open(file, &ide_drivers_show, NULL); } + static struct file_operations ide_drivers_operations = { .open = ide_drivers_open, .read = seq_read, .llseek = seq_lseek, - .release = seq_release, + .release = single_release, }; void proc_ide_create(void) diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 482544854985..5a3dc46008e6 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -4681,21 +4681,12 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) idetape_add_settings(drive); } -static int idetape_cleanup (ide_drive_t *drive) +static int ide_tape_remove(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); idetape_tape_t *tape = drive->driver_data; - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - if (test_bit(IDETAPE_BUSY, &tape->flags) || drive->usage || - tape->first_stage != NULL || tape->merge_stage_size) { - spin_unlock_irqrestore(&ide_lock, flags); - return 1; - } - spin_unlock_irqrestore(&ide_lock, flags); - DRIVER(drive)->busy = 0; - (void) ide_unregister_subdriver(drive); + ide_unregister_subdriver(drive, tape->driver); ide_unregister_region(tape->disk); @@ -4710,6 +4701,8 @@ static void ide_tape_release(struct kref *kref) ide_drive_t *drive = tape->drive; struct gendisk *g = tape->disk; + BUG_ON(tape->first_stage != NULL || tape->merge_stage_size); + drive->dsc_overlap = 0; drive->driver_data = NULL; devfs_remove("%s/mt", drive->devfs_name); @@ -4747,26 +4740,24 @@ static ide_proc_entry_t idetape_proc[] = { #endif -static int idetape_attach(ide_drive_t *drive); +static int ide_tape_probe(struct device *); -/* - * IDE subdriver functions, registered with ide.c - */ static ide_driver_t idetape_driver = { .owner = THIS_MODULE, - .name = "ide-tape", + .gen_driver = { + .name = "ide-tape", + .bus = &ide_bus_type, + .probe = ide_tape_probe, + .remove = ide_tape_remove, + }, .version = IDETAPE_VERSION, .media = ide_tape, - .busy = 1, .supports_dsc_overlap = 1, - .cleanup = idetape_cleanup, .do_request = idetape_do_request, .end_request = idetape_end_request, .error = __ide_error, .abort = __ide_abort, .proc = idetape_proc, - .attach = idetape_attach, - .drives = LIST_HEAD_INIT(idetape_driver.drives), }; /* @@ -4829,8 +4820,9 @@ static struct block_device_operations idetape_block_ops = { .ioctl = idetape_ioctl, }; -static int idetape_attach (ide_drive_t *drive) +static int ide_tape_probe(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); idetape_tape_t *tape; struct gendisk *g; int minor; @@ -4865,10 +4857,7 @@ static int idetape_attach (ide_drive_t *drive) ide_init_disk(g, drive); - if (ide_register_subdriver(drive, &idetape_driver)) { - printk(KERN_ERR "ide-tape: %s: Failed to register the driver with ide.c\n", drive->name); - goto out_put_disk; - } + ide_register_subdriver(drive, &idetape_driver); memset(tape, 0, sizeof(*tape)); @@ -4902,12 +4891,11 @@ static int idetape_attach (ide_drive_t *drive) ide_register_region(g); return 0; -out_put_disk: - put_disk(g); + out_free_tape: kfree(tape); failed: - return 1; + return -ENODEV; } MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); @@ -4915,7 +4903,7 @@ MODULE_LICENSE("GPL"); static void __exit idetape_exit (void) { - ide_unregister_driver(&idetape_driver); + driver_unregister(&idetape_driver.gen_driver); unregister_chrdev(IDETAPE_MAJOR, "ht"); } @@ -4928,8 +4916,7 @@ static int idetape_init (void) printk(KERN_ERR "ide-tape: Failed to register character device interface\n"); return -EBUSY; } - ide_register_driver(&idetape_driver); - return 0; + return driver_register(&idetape_driver.gen_driver); } module_init(idetape_init); diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 973dec799b5c..dae1bd5b8c3e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -196,8 +196,6 @@ ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */ EXPORT_SYMBOL(ide_hwifs); -static struct list_head ide_drives = LIST_HEAD_INIT(ide_drives); - /* * Do not even *think* about calling this! */ @@ -358,54 +356,6 @@ static int ide_system_bus_speed(void) return system_bus_speed; } -/* - * drives_lock protects the list of drives, drivers_lock the - * list of drivers. Currently nobody takes both at once. - */ - -static DEFINE_SPINLOCK(drives_lock); -static DEFINE_SPINLOCK(drivers_lock); -static LIST_HEAD(drivers); - -/* Iterator for the driver list. */ - -static void *m_start(struct seq_file *m, loff_t *pos) -{ - struct list_head *p; - loff_t l = *pos; - spin_lock(&drivers_lock); - list_for_each(p, &drivers) - if (!l--) - return list_entry(p, ide_driver_t, drivers); - return NULL; -} - -static void *m_next(struct seq_file *m, void *v, loff_t *pos) -{ - struct list_head *p = ((ide_driver_t *)v)->drivers.next; - (*pos)++; - return p==&drivers ? NULL : list_entry(p, ide_driver_t, drivers); -} - -static void m_stop(struct seq_file *m, void *v) -{ - spin_unlock(&drivers_lock); -} - -static int show_driver(struct seq_file *m, void *v) -{ - ide_driver_t *driver = v; - seq_printf(m, "%s version %s\n", driver->name, driver->version); - return 0; -} - -struct seq_operations ide_drivers_op = { - .start = m_start, - .next = m_next, - .stop = m_stop, - .show = show_driver -}; - #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_ide_root; #endif @@ -630,7 +580,7 @@ void ide_unregister(unsigned int index) ide_hwif_t *hwif, *g; static ide_hwif_t tmp_hwif; /* protected by ide_cfg_sem */ ide_hwgroup_t *hwgroup; - int irq_count = 0, unit, i; + int irq_count = 0, unit; BUG_ON(index >= MAX_HWIFS); @@ -643,23 +593,22 @@ void ide_unregister(unsigned int index) goto abort; for (unit = 0; unit < MAX_DRIVES; ++unit) { drive = &hwif->drives[unit]; - if (!drive->present) + if (!drive->present) { + if (drive->devfs_name[0] != '\0') { + devfs_remove(drive->devfs_name); + drive->devfs_name[0] = '\0'; + } continue; - if (drive->usage || DRIVER(drive)->busy) - goto abort; - drive->dead = 1; + } + spin_unlock_irq(&ide_lock); + device_unregister(&drive->gendev); + down(&drive->gendev_rel_sem); + spin_lock_irq(&ide_lock); } hwif->present = 0; spin_unlock_irq(&ide_lock); - for (unit = 0; unit < MAX_DRIVES; ++unit) { - drive = &hwif->drives[unit]; - if (!drive->present) - continue; - DRIVER(drive)->cleanup(drive); - } - destroy_proc_ide_interface(hwif); hwgroup = hwif->hwgroup; @@ -687,44 +636,6 @@ void ide_unregister(unsigned int index) * Remove us from the hwgroup, and free * the hwgroup if we were the only member */ - for (i = 0; i < MAX_DRIVES; ++i) { - drive = &hwif->drives[i]; - if (drive->devfs_name[0] != '\0') { - devfs_remove(drive->devfs_name); - drive->devfs_name[0] = '\0'; - } - if (!drive->present) - continue; - if (drive == drive->next) { - /* special case: last drive from hwgroup. */ - BUG_ON(hwgroup->drive != drive); - hwgroup->drive = NULL; - } else { - ide_drive_t *walk; - - walk = hwgroup->drive; - while (walk->next != drive) - walk = walk->next; - walk->next = drive->next; - if (hwgroup->drive == drive) { - hwgroup->drive = drive->next; - hwgroup->hwif = HWIF(hwgroup->drive); - } - } - BUG_ON(hwgroup->drive == drive); - if (drive->id != NULL) { - kfree(drive->id); - drive->id = NULL; - } - drive->present = 0; - /* Messed up locking ... */ - spin_unlock_irq(&ide_lock); - blk_cleanup_queue(drive->queue); - device_unregister(&drive->gendev); - down(&drive->gendev_rel_sem); - spin_lock_irq(&ide_lock); - drive->queue = NULL; - } if (hwif->next == hwif) { BUG_ON(hwgroup->hwif != hwif); kfree(hwgroup); @@ -1304,73 +1215,6 @@ int system_bus_clock (void) EXPORT_SYMBOL(system_bus_clock); -/* - * Locking is badly broken here - since way back. That sucker is - * root-only, but that's not an excuse... The real question is what - * exclusion rules do we want here. - */ -int ide_replace_subdriver (ide_drive_t *drive, const char *driver) -{ - if (!drive->present || drive->usage || drive->dead) - goto abort; - if (DRIVER(drive)->cleanup(drive)) - goto abort; - strlcpy(drive->driver_req, driver, sizeof(drive->driver_req)); - if (ata_attach(drive)) { - spin_lock(&drives_lock); - list_del_init(&drive->list); - spin_unlock(&drives_lock); - drive->driver_req[0] = 0; - ata_attach(drive); - } else { - drive->driver_req[0] = 0; - } - if (drive->driver && !strcmp(drive->driver->name, driver)) - return 0; -abort: - return 1; -} - -/** - * ata_attach - attach an ATA/ATAPI device - * @drive: drive to attach - * - * Takes a drive that is as yet not assigned to any midlayer IDE - * driver (or is assigned to the default driver) and figures out - * which driver would like to own it. If nobody claims the drive - * then it is automatically attached to the default driver used for - * unclaimed objects. - * - * A return of zero indicates attachment to a driver, of one - * attachment to the default driver. - * - * Takes drivers_lock. - */ - -int ata_attach(ide_drive_t *drive) -{ - struct list_head *p; - spin_lock(&drivers_lock); - list_for_each(p, &drivers) { - ide_driver_t *driver = list_entry(p, ide_driver_t, drivers); - if (!try_module_get(driver->owner)) - continue; - spin_unlock(&drivers_lock); - if (driver->attach(drive) == 0) { - module_put(driver->owner); - drive->gendev.driver = &driver->gen_driver; - return 0; - } - spin_lock(&drivers_lock); - module_put(driver->owner); - } - drive->gendev.driver = NULL; - spin_unlock(&drivers_lock); - if (ide_register_subdriver(drive, NULL)) - panic("ide: default attach failed"); - return 1; -} - static int generic_ide_suspend(struct device *dev, pm_message_t state) { ide_drive_t *drive = dev->driver_data; @@ -2013,27 +1857,11 @@ static void __init probe_for_hwifs (void) #endif } -int ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) +void ide_register_subdriver(ide_drive_t *drive, ide_driver_t *driver) { - unsigned long flags; - - spin_lock_irqsave(&ide_lock, flags); - if (!drive->present || drive->driver != NULL || - drive->usage || drive->dead) { - spin_unlock_irqrestore(&ide_lock, flags); - return 1; - } - drive->driver = driver; - spin_unlock_irqrestore(&ide_lock, flags); - spin_lock(&drives_lock); - list_add_tail(&drive->list, driver ? &driver->drives : &ide_drives); - spin_unlock(&drives_lock); -// printk(KERN_INFO "%s: attached %s driver.\n", drive->name, driver->name); #ifdef CONFIG_PROC_FS - if (driver) - ide_add_proc_entries(drive->proc, driver->proc, drive); + ide_add_proc_entries(drive->proc, driver->proc, drive); #endif - return 0; } EXPORT_SYMBOL(ide_register_subdriver); @@ -2041,136 +1869,51 @@ EXPORT_SYMBOL(ide_register_subdriver); /** * ide_unregister_subdriver - disconnect drive from driver * @drive: drive to unplug + * @driver: driver * * Disconnect a drive from the driver it was attached to and then * clean up the various proc files and other objects attached to it. * - * Takes ide_setting_sem, ide_lock and drives_lock. + * Takes ide_setting_sem and ide_lock. * Caller must hold none of the locks. - * - * No locking versus subdriver unload because we are moving to the - * default driver anyway. Wants double checking. */ -int ide_unregister_subdriver (ide_drive_t *drive) +void ide_unregister_subdriver(ide_drive_t *drive, ide_driver_t *driver) { unsigned long flags; down(&ide_setting_sem); spin_lock_irqsave(&ide_lock, flags); - if (drive->usage || drive->driver == NULL || DRIVER(drive)->busy) { - spin_unlock_irqrestore(&ide_lock, flags); - up(&ide_setting_sem); - return 1; - } #ifdef CONFIG_PROC_FS - ide_remove_proc_entries(drive->proc, DRIVER(drive)->proc); + ide_remove_proc_entries(drive->proc, driver->proc); #endif auto_remove_settings(drive); - drive->driver = NULL; spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); - spin_lock(&drives_lock); - list_del_init(&drive->list); - spin_unlock(&drives_lock); - /* drive will be added to &ide_drives in ata_attach() */ - return 0; } EXPORT_SYMBOL(ide_unregister_subdriver); -static int ide_drive_remove(struct device * dev) -{ - ide_drive_t * drive = container_of(dev,ide_drive_t,gendev); - DRIVER(drive)->cleanup(drive); - return 0; -} - -/** - * ide_register_driver - register IDE device driver - * @driver: the IDE device driver - * - * Register a new device driver and then scan the devices - * on the IDE bus in case any should be attached to the - * driver we have just registered. If so attach them. - * - * Takes drivers_lock and drives_lock. - */ - -int ide_register_driver(ide_driver_t *driver) -{ - struct list_head list; - struct list_head *list_loop; - struct list_head *tmp_storage; - - spin_lock(&drivers_lock); - list_add(&driver->drivers, &drivers); - spin_unlock(&drivers_lock); - - INIT_LIST_HEAD(&list); - spin_lock(&drives_lock); - list_splice_init(&ide_drives, &list); - spin_unlock(&drives_lock); - - list_for_each_safe(list_loop, tmp_storage, &list) { - ide_drive_t *drive = container_of(list_loop, ide_drive_t, list); - list_del_init(&drive->list); - if (drive->present) - ata_attach(drive); - } - driver->gen_driver.name = (char *) driver->name; - driver->gen_driver.bus = &ide_bus_type; - driver->gen_driver.remove = ide_drive_remove; - return driver_register(&driver->gen_driver); -} - -EXPORT_SYMBOL(ide_register_driver); - -/** - * ide_unregister_driver - unregister IDE device driver - * @driver: the IDE device driver - * - * Called when a driver module is being unloaded. We reattach any - * devices to whatever driver claims them next (typically the default - * driver). - * - * Takes drivers_lock and called functions will take ide_setting_sem. - */ - -void ide_unregister_driver(ide_driver_t *driver) -{ - ide_drive_t *drive; - - spin_lock(&drivers_lock); - list_del(&driver->drivers); - spin_unlock(&drivers_lock); - - driver_unregister(&driver->gen_driver); - - while(!list_empty(&driver->drives)) { - drive = list_entry(driver->drives.next, ide_drive_t, list); - if (driver->cleanup(drive)) { - printk(KERN_ERR "%s: cleanup_module() called while still busy\n", drive->name); - BUG(); - } - ata_attach(drive); - } -} - -EXPORT_SYMBOL(ide_unregister_driver); - /* * Probe module */ EXPORT_SYMBOL(ide_lock); +static int ide_bus_match(struct device *dev, struct device_driver *drv) +{ + return 1; +} + struct bus_type ide_bus_type = { .name = "ide", + .match = ide_bus_match, .suspend = generic_ide_suspend, .resume = generic_ide_resume, }; +EXPORT_SYMBOL_GPL(ide_bus_type); + /* * This is gets invoked once during initialization, to set *everything* up */ diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2e2486b035dd..d80c4c9d5a63 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -713,7 +713,6 @@ static void idescsi_add_settings(ide_drive_t *drive) */ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) { - DRIVER(drive)->busy++; if (drive->id && (drive->id->config & 0x0060) == 0x20) set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); set_bit(IDESCSI_TRANSFORM, &scsi->transform); @@ -722,17 +721,16 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) set_bit(IDESCSI_LOG_CMD, &scsi->log); #endif /* IDESCSI_DEBUG_LOG */ idescsi_add_settings(drive); - DRIVER(drive)->busy--; } -static int idescsi_cleanup (ide_drive_t *drive) +static int ide_scsi_remove(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); struct Scsi_Host *scsihost = drive->driver_data; struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); struct gendisk *g = scsi->disk; - if (ide_unregister_subdriver(drive)) - return 1; + ide_unregister_subdriver(drive, scsi->driver); ide_unregister_region(g); @@ -746,7 +744,7 @@ static int idescsi_cleanup (ide_drive_t *drive) return 0; } -static int idescsi_attach(ide_drive_t *drive); +static int ide_scsi_probe(struct device *); #ifdef CONFIG_PROC_FS static ide_proc_entry_t idescsi_proc[] = { @@ -757,24 +755,22 @@ static ide_proc_entry_t idescsi_proc[] = { # define idescsi_proc NULL #endif -/* - * IDE subdriver functions, registered with ide.c - */ static ide_driver_t idescsi_driver = { .owner = THIS_MODULE, - .name = "ide-scsi", + .gen_driver = { + .name = "ide-scsi", + .bus = &ide_bus_type, + .probe = ide_scsi_probe, + .remove = ide_scsi_remove, + }, .version = IDESCSI_VERSION, .media = ide_scsi, - .busy = 0, .supports_dsc_overlap = 0, .proc = idescsi_proc, - .attach = idescsi_attach, - .cleanup = idescsi_cleanup, .do_request = idescsi_do_request, .end_request = idescsi_end_request, .error = idescsi_atapi_error, .abort = idescsi_atapi_abort, - .drives = LIST_HEAD_INIT(idescsi_driver.drives), }; static int idescsi_ide_open(struct inode *inode, struct file *filp) @@ -821,8 +817,6 @@ static struct block_device_operations idescsi_ops = { .ioctl = idescsi_ide_ioctl, }; -static int idescsi_attach(ide_drive_t *drive); - static int idescsi_slave_configure(struct scsi_device * sdp) { /* Configure detected device */ @@ -1095,8 +1089,9 @@ static struct scsi_host_template idescsi_template = { .proc_name = "ide-scsi", }; -static int idescsi_attach(ide_drive_t *drive) +static int ide_scsi_probe(struct device *dev) { + ide_drive_t *drive = to_ide_device(dev); idescsi_scsi_t *idescsi; struct Scsi_Host *host; struct gendisk *g; @@ -1112,7 +1107,7 @@ static int idescsi_attach(ide_drive_t *drive) !drive->present || drive->media == ide_disk || !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) - return 1; + return -ENODEV; g = alloc_disk(1 << PARTN_BITS); if (!g) @@ -1138,20 +1133,19 @@ static int idescsi_attach(ide_drive_t *drive) idescsi->host = host; idescsi->disk = g; g->private_data = &idescsi->driver; - err = ide_register_subdriver(drive, &idescsi_driver); + ide_register_subdriver(drive, &idescsi_driver); + err = 0; + idescsi_setup(drive, idescsi); + g->fops = &idescsi_ops; + ide_register_region(g); + err = scsi_add_host(host, &drive->gendev); if (!err) { - idescsi_setup (drive, idescsi); - g->fops = &idescsi_ops; - ide_register_region(g); - err = scsi_add_host(host, &drive->gendev); - if (!err) { - scsi_scan_host(host); - return 0; - } - /* fall through on error */ - ide_unregister_region(g); - ide_unregister_subdriver(drive); + scsi_scan_host(host); + return 0; } + /* fall through on error */ + ide_unregister_region(g); + ide_unregister_subdriver(drive, &idescsi_driver); put_disk(g); out_host_put: @@ -1161,12 +1155,12 @@ out_host_put: static int __init init_idescsi_module(void) { - return ide_register_driver(&idescsi_driver); + return driver_register(&idescsi_driver.gen_driver); } static void __exit exit_idescsi_module(void) { - ide_unregister_driver(&idescsi_driver); + driver_unregister(&idescsi_driver.gen_driver); } module_init(init_idescsi_module); -- cgit v1.2.2 From 41bb4c43b34bcde7eb62cf19acdcf9f2eb13801d Mon Sep 17 00:00:00 2001 From: Stuart Hayes Date: Thu, 26 May 2005 15:38:45 +0200 Subject: [PATCH] ide-scsi: kmap scatter/gather before doing PIO From: Stuart Hayes The system can panic with a null pointer dereference using ide-scsi if PIO is being done on scatter gather pages that are in high memory, because page_address() returns 0. We are actually seeing this using a tape drive. This patch will kmap_atomic() the pages before performing PIO. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/scsi/ide-scsi.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index d80c4c9d5a63..83f062ed9082 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c @@ -179,8 +179,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne return; } count = min(pc->sg->length - pc->b_count, bcount); - buf = page_address(pc->sg->page) + pc->sg->offset; - drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count); + if (PageHighMem(pc->sg->page)) { + unsigned long flags; + + local_irq_save(flags); + buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset; + drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count); + kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); + local_irq_restore(flags); + } else { + buf = page_address(pc->sg->page) + pc->sg->offset; + drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count); + } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { pc->sg++; @@ -201,8 +211,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign return; } count = min(pc->sg->length - pc->b_count, bcount); - buf = page_address(pc->sg->page) + pc->sg->offset; - drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count); + if (PageHighMem(pc->sg->page)) { + unsigned long flags; + + local_irq_save(flags); + buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset; + drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count); + kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); + local_irq_restore(flags); + } else { + buf = page_address(pc->sg->page) + pc->sg->offset; + drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count); + } bcount -= count; pc->b_count += count; if (pc->b_count == pc->sg->length) { pc->sg++; -- cgit v1.2.2 From 284e423811495f632a7a334b2b93caba07d4f778 Mon Sep 17 00:00:00 2001 From: Marcello Maggioni Date: Thu, 26 May 2005 15:47:35 +0200 Subject: [PATCH] timeout at boottime with NEC3500A (and possibly others) when inserted a CD in it From: Marcello Maggioni Problem: Some drives (NEC 3500, TDK 1616N, Mad-dog MD-16XDVD9, RICOH MP5163DA, Memorex DVD9 drive and IO-DATA's too for sure), if a CD/DVD is inserted into the tray when the system is booted and if before the OS bootup the BIOS checked for the presence of a bootable CD/DVD into the drive, during the IDE probe phase the drive may result busy and remain so for the next 25/30 seconds . This cause the drive to be skipped during the booting phase and not begin usable until the next reboot (if the reboot goes well and the drive doesn't timeout again). Solution: Rising the timeout time from 10 seconds to 35 seconds (during these 35 seconds every drive should wake up for sure according to the tests I've done). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-probe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 53b84a84f6cb..5d876f53c697 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -697,13 +697,13 @@ static int wait_hwif_ready(ide_hwif_t *hwif) SELECT_DRIVE(&hwif->drives[0]); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); mdelay(2); - rc = ide_wait_not_busy(hwif, 10000); + rc = ide_wait_not_busy(hwif, 35000); if (rc) return rc; SELECT_DRIVE(&hwif->drives[1]); hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); mdelay(2); - rc = ide_wait_not_busy(hwif, 10000); + rc = ide_wait_not_busy(hwif, 35000); /* Exit function with master reselected (let's be sane) */ SELECT_DRIVE(&hwif->drives[0]); -- cgit v1.2.2 From 2f872f0401d4b470990864fbf99c19130f25ad4d Mon Sep 17 00:00:00 2001 From: Jay Vosburgh Date: Thu, 26 May 2005 12:56:59 -0700 Subject: [BONDING]: bonding using arp_ip_target may stay down with active path Correcting the list traversal makes the problem go away. Signed-off-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 770e28f98fd5..269a5e407349 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3037,7 +3037,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) bond_set_slave_inactive_flags(bond->current_arp_slave); /* search for next candidate */ - bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave) { + bond_for_each_slave_from(bond, slave, i, bond->current_arp_slave->next) { if (IS_UP(slave->dev)) { slave->link = BOND_LINK_BACK; bond_set_slave_active_flags(slave); -- cgit v1.2.2 From b6016b767397258b58163494a869f8f1199e6897 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 26 May 2005 13:03:09 -0700 Subject: [BNX2]: New Broadcom gigabit network driver. A new driver bnx2 for Broadcom bcm5706 is available. The patch also includes new 1000BASE-X advertisement bit definitions in mii.h Thanks to David Miller and Jeff Garzik for reviewing and their valuable feedback. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/Kconfig | 9 + drivers/net/Makefile | 1 + drivers/net/bnx2.c | 5530 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/bnx2.h | 4352 ++++++++++++++++++++++++++++++++++++++ drivers/net/bnx2_fw.h | 2468 ++++++++++++++++++++++ 5 files changed, 12360 insertions(+) create mode 100644 drivers/net/bnx2.c create mode 100644 drivers/net/bnx2.h create mode 100644 drivers/net/bnx2_fw.h (limited to 'drivers') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 3a0a55b62aaf..9e6501d98817 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2031,6 +2031,15 @@ config TIGON3 To compile this driver as a module, choose M here: the module will be called tg3. This is recommended. +config BNX2 + tristate "Broadcom NetXtremeII support" + depends on PCI + help + This driver supports Broadcom NetXtremeII gigabit Ethernet cards. + + To compile this driver as a module, choose M here: the module + will be called bnx2. This is recommended. + config GIANFAR tristate "Gianfar Ethernet" depends on 85xx || 83xx diff --git a/drivers/net/Makefile b/drivers/net/Makefile index e038d55e4f6f..30c7567001fe 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_NS83820) += ns83820.o obj-$(CONFIG_STNIC) += stnic.o 8390.o obj-$(CONFIG_FEALNX) += fealnx.o obj-$(CONFIG_TIGON3) += tg3.o +obj-$(CONFIG_BNX2) += bnx2.o obj-$(CONFIG_TC35815) += tc35815.o obj-$(CONFIG_SK98LIN) += sk98lin/ obj-$(CONFIG_SKFP) += skfp/ diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c new file mode 100644 index 000000000000..8acc655ec1e8 --- /dev/null +++ b/drivers/net/bnx2.c @@ -0,0 +1,5530 @@ +/* bnx2.c: Broadcom NX2 network driver. + * + * Copyright (c) 2004, 2005 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + * + * Written by: Michael Chan (mchan@broadcom.com) + */ + +#include "bnx2.h" +#include "bnx2_fw.h" + +#define DRV_MODULE_NAME "bnx2" +#define PFX DRV_MODULE_NAME ": " +#define DRV_MODULE_VERSION "1.2.19" +#define DRV_MODULE_RELDATE "May 23, 2005" + +#define RUN_AT(x) (jiffies + (x)) + +/* Time in jiffies before concluding the transmitter is hung. */ +#define TX_TIMEOUT (5*HZ) + +static char version[] __devinitdata = + "Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; + +MODULE_AUTHOR("Michael Chan "); +MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_MODULE_VERSION); + +static int disable_msi = 0; + +module_param(disable_msi, int, 0); +MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); + +typedef enum { + BCM5706 = 0, + NC370T, + NC370I, + BCM5706S, + NC370F, +} board_t; + +/* indexed by board_t, above */ +static struct { + char *name; +} board_info[] __devinitdata = { + { "Broadcom NetXtreme II BCM5706 1000Base-T" }, + { "HP NC370T Multifunction Gigabit Server Adapter" }, + { "HP NC370i Multifunction Gigabit Server Adapter" }, + { "Broadcom NetXtreme II BCM5706 1000Base-SX" }, + { "HP NC370F Multifunction Gigabit Server Adapter" }, + { 0 }, + }; + +static struct pci_device_id bnx2_pci_tbl[] = { + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, + PCI_VENDOR_ID_HP, 0x3101, 0, 0, NC370T }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, + PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, + PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F }, + { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S }, + { 0, } +}; + +static struct flash_spec flash_table[] = +{ + /* Slow EEPROM */ + {0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400, + 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, + SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, + "EEPROM - slow"}, + /* Fast EEPROM */ + {0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400, + 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, + SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, + "EEPROM - fast"}, + /* ATMEL AT45DB011B (buffered flash) */ + {0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400, + 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, + BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, + "Buffered flash"}, + /* Saifun SA25F005 (non-buffered flash) */ + /* strap, cfg1, & write1 need updates */ + {0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406, + 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, + SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, + "Non-buffered flash (64kB)"}, + /* Saifun SA25F010 (non-buffered flash) */ + /* strap, cfg1, & write1 need updates */ + {0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406, + 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, + SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, + "Non-buffered flash (128kB)"}, + /* Saifun SA25F020 (non-buffered flash) */ + /* strap, cfg1, & write1 need updates */ + {0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406, + 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, + SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, + "Non-buffered flash (256kB)"}, +}; + +MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl); + +static u32 +bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset) +{ + REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); + return (REG_RD(bp, BNX2_PCICFG_REG_WINDOW)); +} + +static void +bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val) +{ + REG_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset); + REG_WR(bp, BNX2_PCICFG_REG_WINDOW, val); +} + +static void +bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val) +{ + offset += cid_addr; + REG_WR(bp, BNX2_CTX_DATA_ADR, offset); + REG_WR(bp, BNX2_CTX_DATA, val); +} + +static int +bnx2_read_phy(struct bnx2 *bp, u32 reg, u32 *val) +{ + u32 val1; + int i, ret; + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); + val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL; + + REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); + REG_RD(bp, BNX2_EMAC_MDIO_MODE); + + udelay(40); + } + + val1 = (bp->phy_addr << 21) | (reg << 16) | + BNX2_EMAC_MDIO_COMM_COMMAND_READ | BNX2_EMAC_MDIO_COMM_DISEXT | + BNX2_EMAC_MDIO_COMM_START_BUSY; + REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1); + + for (i = 0; i < 50; i++) { + udelay(10); + + val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); + if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + + val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); + val1 &= BNX2_EMAC_MDIO_COMM_DATA; + + break; + } + } + + if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) { + *val = 0x0; + ret = -EBUSY; + } + else { + *val = val1; + ret = 0; + } + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); + val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL; + + REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); + REG_RD(bp, BNX2_EMAC_MDIO_MODE); + + udelay(40); + } + + return ret; +} + +static int +bnx2_write_phy(struct bnx2 *bp, u32 reg, u32 val) +{ + u32 val1; + int i, ret; + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); + val1 &= ~BNX2_EMAC_MDIO_MODE_AUTO_POLL; + + REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); + REG_RD(bp, BNX2_EMAC_MDIO_MODE); + + udelay(40); + } + + val1 = (bp->phy_addr << 21) | (reg << 16) | val | + BNX2_EMAC_MDIO_COMM_COMMAND_WRITE | + BNX2_EMAC_MDIO_COMM_START_BUSY | BNX2_EMAC_MDIO_COMM_DISEXT; + REG_WR(bp, BNX2_EMAC_MDIO_COMM, val1); + + for (i = 0; i < 50; i++) { + udelay(10); + + val1 = REG_RD(bp, BNX2_EMAC_MDIO_COMM); + if (!(val1 & BNX2_EMAC_MDIO_COMM_START_BUSY)) { + udelay(5); + break; + } + } + + if (val1 & BNX2_EMAC_MDIO_COMM_START_BUSY) + ret = -EBUSY; + else + ret = 0; + + if (bp->phy_flags & PHY_INT_MODE_AUTO_POLLING_FLAG) { + val1 = REG_RD(bp, BNX2_EMAC_MDIO_MODE); + val1 |= BNX2_EMAC_MDIO_MODE_AUTO_POLL; + + REG_WR(bp, BNX2_EMAC_MDIO_MODE, val1); + REG_RD(bp, BNX2_EMAC_MDIO_MODE); + + udelay(40); + } + + return ret; +} + +static void +bnx2_disable_int(struct bnx2 *bp) +{ + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_MASK_INT); + REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD); +} + +static void +bnx2_enable_int(struct bnx2 *bp) +{ + u32 val; + + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | bp->last_status_idx); + + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); +} + +static void +bnx2_disable_int_sync(struct bnx2 *bp) +{ + atomic_inc(&bp->intr_sem); + bnx2_disable_int(bp); + synchronize_irq(bp->pdev->irq); +} + +static void +bnx2_netif_stop(struct bnx2 *bp) +{ + bnx2_disable_int_sync(bp); + if (netif_running(bp->dev)) { + netif_poll_disable(bp->dev); + netif_tx_disable(bp->dev); + bp->dev->trans_start = jiffies; /* prevent tx timeout */ + } +} + +static void +bnx2_netif_start(struct bnx2 *bp) +{ + if (atomic_dec_and_test(&bp->intr_sem)) { + if (netif_running(bp->dev)) { + netif_wake_queue(bp->dev); + netif_poll_enable(bp->dev); + bnx2_enable_int(bp); + } + } +} + +static void +bnx2_free_mem(struct bnx2 *bp) +{ + if (bp->stats_blk) { + pci_free_consistent(bp->pdev, sizeof(struct statistics_block), + bp->stats_blk, bp->stats_blk_mapping); + bp->stats_blk = NULL; + } + if (bp->status_blk) { + pci_free_consistent(bp->pdev, sizeof(struct status_block), + bp->status_blk, bp->status_blk_mapping); + bp->status_blk = NULL; + } + if (bp->tx_desc_ring) { + pci_free_consistent(bp->pdev, + sizeof(struct tx_bd) * TX_DESC_CNT, + bp->tx_desc_ring, bp->tx_desc_mapping); + bp->tx_desc_ring = NULL; + } + if (bp->tx_buf_ring) { + kfree(bp->tx_buf_ring); + bp->tx_buf_ring = NULL; + } + if (bp->rx_desc_ring) { + pci_free_consistent(bp->pdev, + sizeof(struct rx_bd) * RX_DESC_CNT, + bp->rx_desc_ring, bp->rx_desc_mapping); + bp->rx_desc_ring = NULL; + } + if (bp->rx_buf_ring) { + kfree(bp->rx_buf_ring); + bp->rx_buf_ring = NULL; + } +} + +static int +bnx2_alloc_mem(struct bnx2 *bp) +{ + bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT, + GFP_KERNEL); + if (bp->tx_buf_ring == NULL) + return -ENOMEM; + + memset(bp->tx_buf_ring, 0, sizeof(struct sw_bd) * TX_DESC_CNT); + bp->tx_desc_ring = pci_alloc_consistent(bp->pdev, + sizeof(struct tx_bd) * + TX_DESC_CNT, + &bp->tx_desc_mapping); + if (bp->tx_desc_ring == NULL) + goto alloc_mem_err; + + bp->rx_buf_ring = kmalloc(sizeof(struct sw_bd) * RX_DESC_CNT, + GFP_KERNEL); + if (bp->rx_buf_ring == NULL) + goto alloc_mem_err; + + memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT); + bp->rx_desc_ring = pci_alloc_consistent(bp->pdev, + sizeof(struct rx_bd) * + RX_DESC_CNT, + &bp->rx_desc_mapping); + if (bp->rx_desc_ring == NULL) + goto alloc_mem_err; + + bp->status_blk = pci_alloc_consistent(bp->pdev, + sizeof(struct status_block), + &bp->status_blk_mapping); + if (bp->status_blk == NULL) + goto alloc_mem_err; + + memset(bp->status_blk, 0, sizeof(struct status_block)); + + bp->stats_blk = pci_alloc_consistent(bp->pdev, + sizeof(struct statistics_block), + &bp->stats_blk_mapping); + if (bp->stats_blk == NULL) + goto alloc_mem_err; + + memset(bp->stats_blk, 0, sizeof(struct statistics_block)); + + return 0; + +alloc_mem_err: + bnx2_free_mem(bp); + return -ENOMEM; +} + +static void +bnx2_report_link(struct bnx2 *bp) +{ + if (bp->link_up) { + netif_carrier_on(bp->dev); + printk(KERN_INFO PFX "%s NIC Link is Up, ", bp->dev->name); + + printk("%d Mbps ", bp->line_speed); + + if (bp->duplex == DUPLEX_FULL) + printk("full duplex"); + else + printk("half duplex"); + + if (bp->flow_ctrl) { + if (bp->flow_ctrl & FLOW_CTRL_RX) { + printk(", receive "); + if (bp->flow_ctrl & FLOW_CTRL_TX) + printk("& transmit "); + } + else { + printk(", transmit "); + } + printk("flow control ON"); + } + printk("\n"); + } + else { + netif_carrier_off(bp->dev); + printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name); + } +} + +static void +bnx2_resolve_flow_ctrl(struct bnx2 *bp) +{ + u32 local_adv, remote_adv; + + bp->flow_ctrl = 0; + if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) != + (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) { + + if (bp->duplex == DUPLEX_FULL) { + bp->flow_ctrl = bp->req_flow_ctrl; + } + return; + } + + if (bp->duplex != DUPLEX_FULL) { + return; + } + + bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); + bnx2_read_phy(bp, MII_LPA, &remote_adv); + + if (bp->phy_flags & PHY_SERDES_FLAG) { + u32 new_local_adv = 0; + u32 new_remote_adv = 0; + + if (local_adv & ADVERTISE_1000XPAUSE) + new_local_adv |= ADVERTISE_PAUSE_CAP; + if (local_adv & ADVERTISE_1000XPSE_ASYM) + new_local_adv |= ADVERTISE_PAUSE_ASYM; + if (remote_adv & ADVERTISE_1000XPAUSE) + new_remote_adv |= ADVERTISE_PAUSE_CAP; + if (remote_adv & ADVERTISE_1000XPSE_ASYM) + new_remote_adv |= ADVERTISE_PAUSE_ASYM; + + local_adv = new_local_adv; + remote_adv = new_remote_adv; + } + + /* See Table 28B-3 of 802.3ab-1999 spec. */ + if (local_adv & ADVERTISE_PAUSE_CAP) { + if(local_adv & ADVERTISE_PAUSE_ASYM) { + if (remote_adv & ADVERTISE_PAUSE_CAP) { + bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; + } + else if (remote_adv & ADVERTISE_PAUSE_ASYM) { + bp->flow_ctrl = FLOW_CTRL_RX; + } + } + else { + if (remote_adv & ADVERTISE_PAUSE_CAP) { + bp->flow_ctrl = FLOW_CTRL_TX | FLOW_CTRL_RX; + } + } + } + else if (local_adv & ADVERTISE_PAUSE_ASYM) { + if ((remote_adv & ADVERTISE_PAUSE_CAP) && + (remote_adv & ADVERTISE_PAUSE_ASYM)) { + + bp->flow_ctrl = FLOW_CTRL_TX; + } + } +} + +static int +bnx2_serdes_linkup(struct bnx2 *bp) +{ + u32 bmcr, local_adv, remote_adv, common; + + bp->link_up = 1; + bp->line_speed = SPEED_1000; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + if (bmcr & BMCR_FULLDPLX) { + bp->duplex = DUPLEX_FULL; + } + else { + bp->duplex = DUPLEX_HALF; + } + + if (!(bmcr & BMCR_ANENABLE)) { + return 0; + } + + bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); + bnx2_read_phy(bp, MII_LPA, &remote_adv); + + common = local_adv & remote_adv; + if (common & (ADVERTISE_1000XHALF | ADVERTISE_1000XFULL)) { + + if (common & ADVERTISE_1000XFULL) { + bp->duplex = DUPLEX_FULL; + } + else { + bp->duplex = DUPLEX_HALF; + } + } + + return 0; +} + +static int +bnx2_copper_linkup(struct bnx2 *bp) +{ + u32 bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + if (bmcr & BMCR_ANENABLE) { + u32 local_adv, remote_adv, common; + + bnx2_read_phy(bp, MII_CTRL1000, &local_adv); + bnx2_read_phy(bp, MII_STAT1000, &remote_adv); + + common = local_adv & (remote_adv >> 2); + if (common & ADVERTISE_1000FULL) { + bp->line_speed = SPEED_1000; + bp->duplex = DUPLEX_FULL; + } + else if (common & ADVERTISE_1000HALF) { + bp->line_speed = SPEED_1000; + bp->duplex = DUPLEX_HALF; + } + else { + bnx2_read_phy(bp, MII_ADVERTISE, &local_adv); + bnx2_read_phy(bp, MII_LPA, &remote_adv); + + common = local_adv & remote_adv; + if (common & ADVERTISE_100FULL) { + bp->line_speed = SPEED_100; + bp->duplex = DUPLEX_FULL; + } + else if (common & ADVERTISE_100HALF) { + bp->line_speed = SPEED_100; + bp->duplex = DUPLEX_HALF; + } + else if (common & ADVERTISE_10FULL) { + bp->line_speed = SPEED_10; + bp->duplex = DUPLEX_FULL; + } + else if (common & ADVERTISE_10HALF) { + bp->line_speed = SPEED_10; + bp->duplex = DUPLEX_HALF; + } + else { + bp->line_speed = 0; + bp->link_up = 0; + } + } + } + else { + if (bmcr & BMCR_SPEED100) { + bp->line_speed = SPEED_100; + } + else { + bp->line_speed = SPEED_10; + } + if (bmcr & BMCR_FULLDPLX) { + bp->duplex = DUPLEX_FULL; + } + else { + bp->duplex = DUPLEX_HALF; + } + } + + return 0; +} + +static int +bnx2_set_mac_link(struct bnx2 *bp) +{ + u32 val; + + REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x2620); + if (bp->link_up && (bp->line_speed == SPEED_1000) && + (bp->duplex == DUPLEX_HALF)) { + REG_WR(bp, BNX2_EMAC_TX_LENGTHS, 0x26ff); + } + + /* Configure the EMAC mode register. */ + val = REG_RD(bp, BNX2_EMAC_MODE); + + val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX | + BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK); + + if (bp->link_up) { + if (bp->line_speed != SPEED_1000) + val |= BNX2_EMAC_MODE_PORT_MII; + else + val |= BNX2_EMAC_MODE_PORT_GMII; + } + else { + val |= BNX2_EMAC_MODE_PORT_GMII; + } + + /* Set the MAC to operate in the appropriate duplex mode. */ + if (bp->duplex == DUPLEX_HALF) + val |= BNX2_EMAC_MODE_HALF_DUPLEX; + REG_WR(bp, BNX2_EMAC_MODE, val); + + /* Enable/disable rx PAUSE. */ + bp->rx_mode &= ~BNX2_EMAC_RX_MODE_FLOW_EN; + + if (bp->flow_ctrl & FLOW_CTRL_RX) + bp->rx_mode |= BNX2_EMAC_RX_MODE_FLOW_EN; + REG_WR(bp, BNX2_EMAC_RX_MODE, bp->rx_mode); + + /* Enable/disable tx PAUSE. */ + val = REG_RD(bp, BNX2_EMAC_TX_MODE); + val &= ~BNX2_EMAC_TX_MODE_FLOW_EN; + + if (bp->flow_ctrl & FLOW_CTRL_TX) + val |= BNX2_EMAC_TX_MODE_FLOW_EN; + REG_WR(bp, BNX2_EMAC_TX_MODE, val); + + /* Acknowledge the interrupt. */ + REG_WR(bp, BNX2_EMAC_STATUS, BNX2_EMAC_STATUS_LINK_CHANGE); + + return 0; +} + +static int +bnx2_set_link(struct bnx2 *bp) +{ + u32 bmsr; + u8 link_up; + + if (bp->loopback == MAC_LOOPBACK) { + bp->link_up = 1; + return 0; + } + + link_up = bp->link_up; + + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + + if ((bp->phy_flags & PHY_SERDES_FLAG) && + (CHIP_NUM(bp) == CHIP_NUM_5706)) { + u32 val; + + val = REG_RD(bp, BNX2_EMAC_STATUS); + if (val & BNX2_EMAC_STATUS_LINK) + bmsr |= BMSR_LSTATUS; + else + bmsr &= ~BMSR_LSTATUS; + } + + if (bmsr & BMSR_LSTATUS) { + bp->link_up = 1; + + if (bp->phy_flags & PHY_SERDES_FLAG) { + bnx2_serdes_linkup(bp); + } + else { + bnx2_copper_linkup(bp); + } + bnx2_resolve_flow_ctrl(bp); + } + else { + if ((bp->phy_flags & PHY_SERDES_FLAG) && + (bp->autoneg & AUTONEG_SPEED)) { + + u32 bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + if (!(bmcr & BMCR_ANENABLE)) { + bnx2_write_phy(bp, MII_BMCR, bmcr | + BMCR_ANENABLE); + } + } + bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; + bp->link_up = 0; + } + + if (bp->link_up != link_up) { + bnx2_report_link(bp); + } + + bnx2_set_mac_link(bp); + + return 0; +} + +static int +bnx2_reset_phy(struct bnx2 *bp) +{ + int i; + u32 reg; + + bnx2_write_phy(bp, MII_BMCR, BMCR_RESET); + +#define PHY_RESET_MAX_WAIT 100 + for (i = 0; i < PHY_RESET_MAX_WAIT; i++) { + udelay(10); + + bnx2_read_phy(bp, MII_BMCR, ®); + if (!(reg & BMCR_RESET)) { + udelay(20); + break; + } + } + if (i == PHY_RESET_MAX_WAIT) { + return -EBUSY; + } + return 0; +} + +static u32 +bnx2_phy_get_pause_adv(struct bnx2 *bp) +{ + u32 adv = 0; + + if ((bp->req_flow_ctrl & (FLOW_CTRL_RX | FLOW_CTRL_TX)) == + (FLOW_CTRL_RX | FLOW_CTRL_TX)) { + + if (bp->phy_flags & PHY_SERDES_FLAG) { + adv = ADVERTISE_1000XPAUSE; + } + else { + adv = ADVERTISE_PAUSE_CAP; + } + } + else if (bp->req_flow_ctrl & FLOW_CTRL_TX) { + if (bp->phy_flags & PHY_SERDES_FLAG) { + adv = ADVERTISE_1000XPSE_ASYM; + } + else { + adv = ADVERTISE_PAUSE_ASYM; + } + } + else if (bp->req_flow_ctrl & FLOW_CTRL_RX) { + if (bp->phy_flags & PHY_SERDES_FLAG) { + adv = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM; + } + else { + adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + } + } + return adv; +} + +static int +bnx2_setup_serdes_phy(struct bnx2 *bp) +{ + u32 adv, bmcr; + u32 new_adv = 0; + + if (!(bp->autoneg & AUTONEG_SPEED)) { + u32 new_bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + new_bmcr = bmcr & ~BMCR_ANENABLE; + new_bmcr |= BMCR_SPEED1000; + if (bp->req_duplex == DUPLEX_FULL) { + new_bmcr |= BMCR_FULLDPLX; + } + else { + new_bmcr &= ~BMCR_FULLDPLX; + } + if (new_bmcr != bmcr) { + /* Force a link down visible on the other side */ + if (bp->link_up) { + bnx2_read_phy(bp, MII_ADVERTISE, &adv); + adv &= ~(ADVERTISE_1000XFULL | + ADVERTISE_1000XHALF); + bnx2_write_phy(bp, MII_ADVERTISE, adv); + bnx2_write_phy(bp, MII_BMCR, bmcr | + BMCR_ANRESTART | BMCR_ANENABLE); + + bp->link_up = 0; + netif_carrier_off(bp->dev); + } + bnx2_write_phy(bp, MII_BMCR, new_bmcr); + } + return 0; + } + + if (bp->advertising & ADVERTISED_1000baseT_Full) + new_adv |= ADVERTISE_1000XFULL; + + new_adv |= bnx2_phy_get_pause_adv(bp); + + bnx2_read_phy(bp, MII_ADVERTISE, &adv); + bnx2_read_phy(bp, MII_BMCR, &bmcr); + + bp->serdes_an_pending = 0; + if ((adv != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) { + /* Force a link down visible on the other side */ + if (bp->link_up) { + int i; + + bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); + for (i = 0; i < 110; i++) { + udelay(100); + } + } + + bnx2_write_phy(bp, MII_ADVERTISE, new_adv); + bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | + BMCR_ANENABLE); + bp->serdes_an_pending = SERDES_AN_TIMEOUT / bp->timer_interval; + } + + return 0; +} + +#define ETHTOOL_ALL_FIBRE_SPEED \ + (ADVERTISED_1000baseT_Full) + +#define ETHTOOL_ALL_COPPER_SPEED \ + (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ + ADVERTISED_1000baseT_Full) + +#define PHY_ALL_10_100_SPEED (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL | ADVERTISE_CSMA) + +#define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL) + +static int +bnx2_setup_copper_phy(struct bnx2 *bp) +{ + u32 bmcr; + u32 new_bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + + if (bp->autoneg & AUTONEG_SPEED) { + u32 adv_reg, adv1000_reg; + u32 new_adv_reg = 0; + u32 new_adv1000_reg = 0; + + bnx2_read_phy(bp, MII_ADVERTISE, &adv_reg); + adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + + bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg); + adv1000_reg &= PHY_ALL_1000_SPEED; + + if (bp->advertising & ADVERTISED_10baseT_Half) + new_adv_reg |= ADVERTISE_10HALF; + if (bp->advertising & ADVERTISED_10baseT_Full) + new_adv_reg |= ADVERTISE_10FULL; + if (bp->advertising & ADVERTISED_100baseT_Half) + new_adv_reg |= ADVERTISE_100HALF; + if (bp->advertising & ADVERTISED_100baseT_Full) + new_adv_reg |= ADVERTISE_100FULL; + if (bp->advertising & ADVERTISED_1000baseT_Full) + new_adv1000_reg |= ADVERTISE_1000FULL; + + new_adv_reg |= ADVERTISE_CSMA; + + new_adv_reg |= bnx2_phy_get_pause_adv(bp); + + if ((adv1000_reg != new_adv1000_reg) || + (adv_reg != new_adv_reg) || + ((bmcr & BMCR_ANENABLE) == 0)) { + + bnx2_write_phy(bp, MII_ADVERTISE, new_adv_reg); + bnx2_write_phy(bp, MII_CTRL1000, new_adv1000_reg); + bnx2_write_phy(bp, MII_BMCR, BMCR_ANRESTART | + BMCR_ANENABLE); + } + else if (bp->link_up) { + /* Flow ctrl may have changed from auto to forced */ + /* or vice-versa. */ + + bnx2_resolve_flow_ctrl(bp); + bnx2_set_mac_link(bp); + } + return 0; + } + + new_bmcr = 0; + if (bp->req_line_speed == SPEED_100) { + new_bmcr |= BMCR_SPEED100; + } + if (bp->req_duplex == DUPLEX_FULL) { + new_bmcr |= BMCR_FULLDPLX; + } + if (new_bmcr != bmcr) { + u32 bmsr; + int i = 0; + + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + + if (bmsr & BMSR_LSTATUS) { + /* Force link down */ + bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); + do { + udelay(100); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + i++; + } while ((bmsr & BMSR_LSTATUS) && (i < 620)); + } + + bnx2_write_phy(bp, MII_BMCR, new_bmcr); + + /* Normally, the new speed is setup after the link has + * gone down and up again. In some cases, link will not go + * down so we need to set up the new speed here. + */ + if (bmsr & BMSR_LSTATUS) { + bp->line_speed = bp->req_line_speed; + bp->duplex = bp->req_duplex; + bnx2_resolve_flow_ctrl(bp); + bnx2_set_mac_link(bp); + } + } + return 0; +} + +static int +bnx2_setup_phy(struct bnx2 *bp) +{ + if (bp->loopback == MAC_LOOPBACK) + return 0; + + if (bp->phy_flags & PHY_SERDES_FLAG) { + return (bnx2_setup_serdes_phy(bp)); + } + else { + return (bnx2_setup_copper_phy(bp)); + } +} + +static int +bnx2_init_serdes_phy(struct bnx2 *bp) +{ + bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; + + if (CHIP_NUM(bp) == CHIP_NUM_5706) { + REG_WR(bp, BNX2_MISC_UNUSED0, 0x300); + } + + if (bp->dev->mtu > 1500) { + u32 val; + + /* Set extended packet length bit */ + bnx2_write_phy(bp, 0x18, 0x7); + bnx2_read_phy(bp, 0x18, &val); + bnx2_write_phy(bp, 0x18, (val & 0xfff8) | 0x4000); + + bnx2_write_phy(bp, 0x1c, 0x6c00); + bnx2_read_phy(bp, 0x1c, &val); + bnx2_write_phy(bp, 0x1c, (val & 0x3ff) | 0xec02); + } + else { + u32 val; + + bnx2_write_phy(bp, 0x18, 0x7); + bnx2_read_phy(bp, 0x18, &val); + bnx2_write_phy(bp, 0x18, val & ~0x4007); + + bnx2_write_phy(bp, 0x1c, 0x6c00); + bnx2_read_phy(bp, 0x1c, &val); + bnx2_write_phy(bp, 0x1c, (val & 0x3fd) | 0xec00); + } + + return 0; +} + +static int +bnx2_init_copper_phy(struct bnx2 *bp) +{ + bp->phy_flags |= PHY_CRC_FIX_FLAG; + + if (bp->phy_flags & PHY_CRC_FIX_FLAG) { + bnx2_write_phy(bp, 0x18, 0x0c00); + bnx2_write_phy(bp, 0x17, 0x000a); + bnx2_write_phy(bp, 0x15, 0x310b); + bnx2_write_phy(bp, 0x17, 0x201f); + bnx2_write_phy(bp, 0x15, 0x9506); + bnx2_write_phy(bp, 0x17, 0x401f); + bnx2_write_phy(bp, 0x15, 0x14e2); + bnx2_write_phy(bp, 0x18, 0x0400); + } + + if (bp->dev->mtu > 1500) { + u32 val; + + /* Set extended packet length bit */ + bnx2_write_phy(bp, 0x18, 0x7); + bnx2_read_phy(bp, 0x18, &val); + bnx2_write_phy(bp, 0x18, val | 0x4000); + + bnx2_read_phy(bp, 0x10, &val); + bnx2_write_phy(bp, 0x10, val | 0x1); + } + else { + u32 val; + + bnx2_write_phy(bp, 0x18, 0x7); + bnx2_read_phy(bp, 0x18, &val); + bnx2_write_phy(bp, 0x18, val & ~0x4007); + + bnx2_read_phy(bp, 0x10, &val); + bnx2_write_phy(bp, 0x10, val & ~0x1); + } + + return 0; +} + + +static int +bnx2_init_phy(struct bnx2 *bp) +{ + u32 val; + int rc = 0; + + bp->phy_flags &= ~PHY_INT_MODE_MASK_FLAG; + bp->phy_flags |= PHY_INT_MODE_LINK_READY_FLAG; + + REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); + + bnx2_reset_phy(bp); + + bnx2_read_phy(bp, MII_PHYSID1, &val); + bp->phy_id = val << 16; + bnx2_read_phy(bp, MII_PHYSID2, &val); + bp->phy_id |= val & 0xffff; + + if (bp->phy_flags & PHY_SERDES_FLAG) { + rc = bnx2_init_serdes_phy(bp); + } + else { + rc = bnx2_init_copper_phy(bp); + } + + bnx2_setup_phy(bp); + + return rc; +} + +static int +bnx2_set_mac_loopback(struct bnx2 *bp) +{ + u32 mac_mode; + + mac_mode = REG_RD(bp, BNX2_EMAC_MODE); + mac_mode &= ~BNX2_EMAC_MODE_PORT; + mac_mode |= BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK; + REG_WR(bp, BNX2_EMAC_MODE, mac_mode); + bp->link_up = 1; + return 0; +} + +static int +bnx2_fw_sync(struct bnx2 *bp, u32 msg_data) +{ + int i; + u32 val; + + if (bp->fw_timed_out) + return -EBUSY; + + bp->fw_wr_seq++; + msg_data |= bp->fw_wr_seq; + + REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); + + /* wait for an acknowledgement. */ + for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { + udelay(5); + + val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB); + + if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) + break; + } + + /* If we timed out, inform the firmware that this is the case. */ + if (((val & BNX2_FW_MSG_ACK) != (msg_data & BNX2_DRV_MSG_SEQ)) && + ((msg_data & BNX2_DRV_MSG_DATA) != BNX2_DRV_MSG_DATA_WAIT0)) { + + msg_data &= ~BNX2_DRV_MSG_CODE; + msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; + + REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); + + bp->fw_timed_out = 1; + + return -EBUSY; + } + + return 0; +} + +static void +bnx2_init_context(struct bnx2 *bp) +{ + u32 vcid; + + vcid = 96; + while (vcid) { + u32 vcid_addr, pcid_addr, offset; + + vcid--; + + if (CHIP_ID(bp) == CHIP_ID_5706_A0) { + u32 new_vcid; + + vcid_addr = GET_PCID_ADDR(vcid); + if (vcid & 0x8) { + new_vcid = 0x60 + (vcid & 0xf0) + (vcid & 0x7); + } + else { + new_vcid = vcid; + } + pcid_addr = GET_PCID_ADDR(new_vcid); + } + else { + vcid_addr = GET_CID_ADDR(vcid); + pcid_addr = vcid_addr; + } + + REG_WR(bp, BNX2_CTX_VIRT_ADDR, 0x00); + REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); + + /* Zero out the context. */ + for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) { + CTX_WR(bp, 0x00, offset, 0); + } + + REG_WR(bp, BNX2_CTX_VIRT_ADDR, vcid_addr); + REG_WR(bp, BNX2_CTX_PAGE_TBL, pcid_addr); + } +} + +static int +bnx2_alloc_bad_rbuf(struct bnx2 *bp) +{ + u16 *good_mbuf; + u32 good_mbuf_cnt; + u32 val; + + good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL); + if (good_mbuf == NULL) { + printk(KERN_ERR PFX "Failed to allocate memory in " + "bnx2_alloc_bad_rbuf\n"); + return -ENOMEM; + } + + REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, + BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE); + + good_mbuf_cnt = 0; + + /* Allocate a bunch of mbufs and save the good ones in an array. */ + val = REG_RD_IND(bp, BNX2_RBUF_STATUS1); + while (val & BNX2_RBUF_STATUS1_FREE_COUNT) { + REG_WR_IND(bp, BNX2_RBUF_COMMAND, BNX2_RBUF_COMMAND_ALLOC_REQ); + + val = REG_RD_IND(bp, BNX2_RBUF_FW_BUF_ALLOC); + + val &= BNX2_RBUF_FW_BUF_ALLOC_VALUE; + + /* The addresses with Bit 9 set are bad memory blocks. */ + if (!(val & (1 << 9))) { + good_mbuf[good_mbuf_cnt] = (u16) val; + good_mbuf_cnt++; + } + + val = REG_RD_IND(bp, BNX2_RBUF_STATUS1); + } + + /* Free the good ones back to the mbuf pool thus discarding + * all the bad ones. */ + while (good_mbuf_cnt) { + good_mbuf_cnt--; + + val = good_mbuf[good_mbuf_cnt]; + val = (val << 9) | val | 1; + + REG_WR_IND(bp, BNX2_RBUF_FW_BUF_FREE, val); + } + kfree(good_mbuf); + return 0; +} + +static void +bnx2_set_mac_addr(struct bnx2 *bp) +{ + u32 val; + u8 *mac_addr = bp->dev->dev_addr; + + val = (mac_addr[0] << 8) | mac_addr[1]; + + REG_WR(bp, BNX2_EMAC_MAC_MATCH0, val); + + val = (mac_addr[2] << 24) | (mac_addr[3] << 16) | + (mac_addr[4] << 8) | mac_addr[5]; + + REG_WR(bp, BNX2_EMAC_MAC_MATCH1, val); +} + +static inline int +bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index) +{ + struct sk_buff *skb; + struct sw_bd *rx_buf = &bp->rx_buf_ring[index]; + dma_addr_t mapping; + struct rx_bd *rxbd = &bp->rx_desc_ring[index]; + unsigned long align; + + skb = dev_alloc_skb(bp->rx_buf_size); + if (skb == NULL) { + return -ENOMEM; + } + + if (unlikely((align = (unsigned long) skb->data & 0x7))) { + skb_reserve(skb, 8 - align); + } + + skb->dev = bp->dev; + mapping = pci_map_single(bp->pdev, skb->data, bp->rx_buf_use_size, + PCI_DMA_FROMDEVICE); + + rx_buf->skb = skb; + pci_unmap_addr_set(rx_buf, mapping, mapping); + + rxbd->rx_bd_haddr_hi = (u64) mapping >> 32; + rxbd->rx_bd_haddr_lo = (u64) mapping & 0xffffffff; + + bp->rx_prod_bseq += bp->rx_buf_use_size; + + return 0; +} + +static void +bnx2_phy_int(struct bnx2 *bp) +{ + u32 new_link_state, old_link_state; + + new_link_state = bp->status_blk->status_attn_bits & + STATUS_ATTN_BITS_LINK_STATE; + old_link_state = bp->status_blk->status_attn_bits_ack & + STATUS_ATTN_BITS_LINK_STATE; + if (new_link_state != old_link_state) { + if (new_link_state) { + REG_WR(bp, BNX2_PCICFG_STATUS_BIT_SET_CMD, + STATUS_ATTN_BITS_LINK_STATE); + } + else { + REG_WR(bp, BNX2_PCICFG_STATUS_BIT_CLEAR_CMD, + STATUS_ATTN_BITS_LINK_STATE); + } + bnx2_set_link(bp); + } +} + +static void +bnx2_tx_int(struct bnx2 *bp) +{ + u16 hw_cons, sw_cons, sw_ring_cons; + int tx_free_bd = 0; + + hw_cons = bp->status_blk->status_tx_quick_consumer_index0; + if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { + hw_cons++; + } + sw_cons = bp->tx_cons; + + while (sw_cons != hw_cons) { + struct sw_bd *tx_buf; + struct sk_buff *skb; + int i, last; + + sw_ring_cons = TX_RING_IDX(sw_cons); + + tx_buf = &bp->tx_buf_ring[sw_ring_cons]; + skb = tx_buf->skb; +#ifdef BCM_TSO + /* partial BD completions possible with TSO packets */ + if (skb_shinfo(skb)->tso_size) { + u16 last_idx, last_ring_idx; + + last_idx = sw_cons + + skb_shinfo(skb)->nr_frags + 1; + last_ring_idx = sw_ring_cons + + skb_shinfo(skb)->nr_frags + 1; + if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) { + last_idx++; + } + if (((s16) ((s16) last_idx - (s16) hw_cons)) > 0) { + break; + } + } +#endif + pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping), + skb_headlen(skb), PCI_DMA_TODEVICE); + + tx_buf->skb = NULL; + last = skb_shinfo(skb)->nr_frags; + + for (i = 0; i < last; i++) { + sw_cons = NEXT_TX_BD(sw_cons); + + pci_unmap_page(bp->pdev, + pci_unmap_addr( + &bp->tx_buf_ring[TX_RING_IDX(sw_cons)], + mapping), + skb_shinfo(skb)->frags[i].size, + PCI_DMA_TODEVICE); + } + + sw_cons = NEXT_TX_BD(sw_cons); + + tx_free_bd += last + 1; + + dev_kfree_skb_irq(skb); + + hw_cons = bp->status_blk->status_tx_quick_consumer_index0; + if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) { + hw_cons++; + } + } + + atomic_add(tx_free_bd, &bp->tx_avail_bd); + + if (unlikely(netif_queue_stopped(bp->dev))) { + unsigned long flags; + + spin_lock_irqsave(&bp->tx_lock, flags); + if ((netif_queue_stopped(bp->dev)) && + (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)) { + + netif_wake_queue(bp->dev); + } + spin_unlock_irqrestore(&bp->tx_lock, flags); + } + + bp->tx_cons = sw_cons; + +} + +static inline void +bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb, + u16 cons, u16 prod) +{ + struct sw_bd *cons_rx_buf = &bp->rx_buf_ring[cons]; + struct sw_bd *prod_rx_buf = &bp->rx_buf_ring[prod]; + struct rx_bd *cons_bd = &bp->rx_desc_ring[cons]; + struct rx_bd *prod_bd = &bp->rx_desc_ring[prod]; + + pci_dma_sync_single_for_device(bp->pdev, + pci_unmap_addr(cons_rx_buf, mapping), + bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); + + prod_rx_buf->skb = cons_rx_buf->skb; + pci_unmap_addr_set(prod_rx_buf, mapping, + pci_unmap_addr(cons_rx_buf, mapping)); + + memcpy(prod_bd, cons_bd, 8); + + bp->rx_prod_bseq += bp->rx_buf_use_size; + +} + +static int +bnx2_rx_int(struct bnx2 *bp, int budget) +{ + u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; + struct l2_fhdr *rx_hdr; + int rx_pkt = 0; + + hw_cons = bp->status_blk->status_rx_quick_consumer_index0; + if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) { + hw_cons++; + } + sw_cons = bp->rx_cons; + sw_prod = bp->rx_prod; + + /* Memory barrier necessary as speculative reads of the rx + * buffer can be ahead of the index in the status block + */ + rmb(); + while (sw_cons != hw_cons) { + unsigned int len; + u16 status; + struct sw_bd *rx_buf; + struct sk_buff *skb; + + sw_ring_cons = RX_RING_IDX(sw_cons); + sw_ring_prod = RX_RING_IDX(sw_prod); + + rx_buf = &bp->rx_buf_ring[sw_ring_cons]; + skb = rx_buf->skb; + pci_dma_sync_single_for_cpu(bp->pdev, + pci_unmap_addr(rx_buf, mapping), + bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE); + + rx_hdr = (struct l2_fhdr *) skb->data; + len = rx_hdr->l2_fhdr_pkt_len - 4; + + if (rx_hdr->l2_fhdr_errors & + (L2_FHDR_ERRORS_BAD_CRC | + L2_FHDR_ERRORS_PHY_DECODE | + L2_FHDR_ERRORS_ALIGNMENT | + L2_FHDR_ERRORS_TOO_SHORT | + L2_FHDR_ERRORS_GIANT_FRAME)) { + + goto reuse_rx; + } + + /* Since we don't have a jumbo ring, copy small packets + * if mtu > 1500 + */ + if ((bp->dev->mtu > 1500) && (len <= RX_COPY_THRESH)) { + struct sk_buff *new_skb; + + new_skb = dev_alloc_skb(len + 2); + if (new_skb == NULL) + goto reuse_rx; + + /* aligned copy */ + memcpy(new_skb->data, + skb->data + bp->rx_offset - 2, + len + 2); + + skb_reserve(new_skb, 2); + skb_put(new_skb, len); + new_skb->dev = bp->dev; + + bnx2_reuse_rx_skb(bp, skb, + sw_ring_cons, sw_ring_prod); + + skb = new_skb; + } + else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) { + pci_unmap_single(bp->pdev, + pci_unmap_addr(rx_buf, mapping), + bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); + + skb_reserve(skb, bp->rx_offset); + skb_put(skb, len); + } + else { +reuse_rx: + bnx2_reuse_rx_skb(bp, skb, + sw_ring_cons, sw_ring_prod); + goto next_rx; + } + + skb->protocol = eth_type_trans(skb, bp->dev); + + if ((len > (bp->dev->mtu + ETH_HLEN)) && + (htons(skb->protocol) != 0x8100)) { + + dev_kfree_skb_irq(skb); + goto next_rx; + + } + + status = rx_hdr->l2_fhdr_status; + skb->ip_summed = CHECKSUM_NONE; + if (bp->rx_csum && + (status & (L2_FHDR_STATUS_TCP_SEGMENT | + L2_FHDR_STATUS_UDP_DATAGRAM))) { + + u16 cksum = rx_hdr->l2_fhdr_tcp_udp_xsum; + + if (cksum == 0xffff) + skb->ip_summed = CHECKSUM_UNNECESSARY; + } + +#ifdef BCM_VLAN + if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) && (bp->vlgrp != 0)) { + vlan_hwaccel_receive_skb(skb, bp->vlgrp, + rx_hdr->l2_fhdr_vlan_tag); + } + else +#endif + netif_receive_skb(skb); + + bp->dev->last_rx = jiffies; + rx_pkt++; + +next_rx: + rx_buf->skb = NULL; + + sw_cons = NEXT_RX_BD(sw_cons); + sw_prod = NEXT_RX_BD(sw_prod); + + if ((rx_pkt == budget)) + break; + } + bp->rx_cons = sw_cons; + bp->rx_prod = sw_prod; + + REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, sw_prod); + + REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); + + mmiowb(); + + return rx_pkt; + +} + +/* MSI ISR - The only difference between this and the INTx ISR + * is that the MSI interrupt is always serviced. + */ +static irqreturn_t +bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = dev_instance; + struct bnx2 *bp = dev->priv; + + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | + BNX2_PCICFG_INT_ACK_CMD_MASK_INT); + + /* Return here if interrupt is disabled. */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + return IRQ_RETVAL(1); + } + + if (netif_rx_schedule_prep(dev)) { + __netif_rx_schedule(dev); + } + + return IRQ_RETVAL(1); +} + +static irqreturn_t +bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs) +{ + struct net_device *dev = dev_instance; + struct bnx2 *bp = dev->priv; + + /* When using INTx, it is possible for the interrupt to arrive + * at the CPU before the status block posted prior to the + * interrupt. Reading a register will flush the status block. + * When using MSI, the MSI message will always complete after + * the status block write. + */ + if ((bp->status_blk->status_idx == bp->last_status_idx) || + (REG_RD(bp, BNX2_PCICFG_MISC_STATUS) & + BNX2_PCICFG_MISC_STATUS_INTA_VALUE)) + return IRQ_RETVAL(0); + + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | + BNX2_PCICFG_INT_ACK_CMD_MASK_INT); + + /* Return here if interrupt is shared and is disabled. */ + if (unlikely(atomic_read(&bp->intr_sem) != 0)) { + return IRQ_RETVAL(1); + } + + if (netif_rx_schedule_prep(dev)) { + __netif_rx_schedule(dev); + } + + return IRQ_RETVAL(1); +} + +static int +bnx2_poll(struct net_device *dev, int *budget) +{ + struct bnx2 *bp = dev->priv; + int rx_done = 1; + + bp->last_status_idx = bp->status_blk->status_idx; + + rmb(); + if ((bp->status_blk->status_attn_bits & + STATUS_ATTN_BITS_LINK_STATE) != + (bp->status_blk->status_attn_bits_ack & + STATUS_ATTN_BITS_LINK_STATE)) { + + unsigned long flags; + + spin_lock_irqsave(&bp->phy_lock, flags); + bnx2_phy_int(bp); + spin_unlock_irqrestore(&bp->phy_lock, flags); + } + + if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) { + bnx2_tx_int(bp); + } + + if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) { + int orig_budget = *budget; + int work_done; + + if (orig_budget > dev->quota) + orig_budget = dev->quota; + + work_done = bnx2_rx_int(bp, orig_budget); + *budget -= work_done; + dev->quota -= work_done; + + if (work_done >= orig_budget) { + rx_done = 0; + } + } + + if (rx_done) { + netif_rx_complete(dev); + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, + BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID | + bp->last_status_idx); + return 0; + } + + return 1; +} + +/* Called with rtnl_lock from vlan functions and also dev->xmit_lock + * from set_multicast. + */ +static void +bnx2_set_rx_mode(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + u32 rx_mode, sort_mode; + int i; + unsigned long flags; + + spin_lock_irqsave(&bp->phy_lock, flags); + + rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS | + BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG); + sort_mode = 1 | BNX2_RPM_SORT_USER0_BC_EN; +#ifdef BCM_VLAN + if (!bp->vlgrp) { + rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; + } +#else + rx_mode |= BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG; +#endif + if (dev->flags & IFF_PROMISC) { + /* Promiscuous mode. */ + rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; + sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN; + } + else if (dev->flags & IFF_ALLMULTI) { + for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { + REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4), + 0xffffffff); + } + sort_mode |= BNX2_RPM_SORT_USER0_MC_EN; + } + else { + /* Accept one or more multicast(s). */ + struct dev_mc_list *mclist; + u32 mc_filter[NUM_MC_HASH_REGISTERS]; + u32 regidx; + u32 bit; + u32 crc; + + memset(mc_filter, 0, 4 * NUM_MC_HASH_REGISTERS); + + for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; + i++, mclist = mclist->next) { + + crc = ether_crc_le(ETH_ALEN, mclist->dmi_addr); + bit = crc & 0xff; + regidx = (bit & 0xe0) >> 5; + bit &= 0x1f; + mc_filter[regidx] |= (1 << bit); + } + + for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { + REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4), + mc_filter[i]); + } + + sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; + } + + if (rx_mode != bp->rx_mode) { + bp->rx_mode = rx_mode; + REG_WR(bp, BNX2_EMAC_RX_MODE, rx_mode); + } + + REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0); + REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode); + REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA); + + spin_unlock_irqrestore(&bp->phy_lock, flags); +} + +static void +load_rv2p_fw(struct bnx2 *bp, u32 *rv2p_code, u32 rv2p_code_len, + u32 rv2p_proc) +{ + int i; + u32 val; + + + for (i = 0; i < rv2p_code_len; i += 8) { + REG_WR(bp, BNX2_RV2P_INSTR_HIGH, *rv2p_code); + rv2p_code++; + REG_WR(bp, BNX2_RV2P_INSTR_LOW, *rv2p_code); + rv2p_code++; + + if (rv2p_proc == RV2P_PROC1) { + val = (i / 8) | BNX2_RV2P_PROC1_ADDR_CMD_RDWR; + REG_WR(bp, BNX2_RV2P_PROC1_ADDR_CMD, val); + } + else { + val = (i / 8) | BNX2_RV2P_PROC2_ADDR_CMD_RDWR; + REG_WR(bp, BNX2_RV2P_PROC2_ADDR_CMD, val); + } + } + + /* Reset the processor, un-stall is done later. */ + if (rv2p_proc == RV2P_PROC1) { + REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC1_RESET); + } + else { + REG_WR(bp, BNX2_RV2P_COMMAND, BNX2_RV2P_COMMAND_PROC2_RESET); + } +} + +static void +load_cpu_fw(struct bnx2 *bp, struct cpu_reg *cpu_reg, struct fw_info *fw) +{ + u32 offset; + u32 val; + + /* Halt the CPU. */ + val = REG_RD_IND(bp, cpu_reg->mode); + val |= cpu_reg->mode_value_halt; + REG_WR_IND(bp, cpu_reg->mode, val); + REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); + + /* Load the Text area. */ + offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base); + if (fw->text) { + int j; + + for (j = 0; j < (fw->text_len / 4); j++, offset += 4) { + REG_WR_IND(bp, offset, fw->text[j]); + } + } + + /* Load the Data area. */ + offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base); + if (fw->data) { + int j; + + for (j = 0; j < (fw->data_len / 4); j++, offset += 4) { + REG_WR_IND(bp, offset, fw->data[j]); + } + } + + /* Load the SBSS area. */ + offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base); + if (fw->sbss) { + int j; + + for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) { + REG_WR_IND(bp, offset, fw->sbss[j]); + } + } + + /* Load the BSS area. */ + offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base); + if (fw->bss) { + int j; + + for (j = 0; j < (fw->bss_len/4); j++, offset += 4) { + REG_WR_IND(bp, offset, fw->bss[j]); + } + } + + /* Load the Read-Only area. */ + offset = cpu_reg->spad_base + + (fw->rodata_addr - cpu_reg->mips_view_base); + if (fw->rodata) { + int j; + + for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) { + REG_WR_IND(bp, offset, fw->rodata[j]); + } + } + + /* Clear the pre-fetch instruction. */ + REG_WR_IND(bp, cpu_reg->inst, 0); + REG_WR_IND(bp, cpu_reg->pc, fw->start_addr); + + /* Start the CPU. */ + val = REG_RD_IND(bp, cpu_reg->mode); + val &= ~cpu_reg->mode_value_halt; + REG_WR_IND(bp, cpu_reg->state, cpu_reg->state_value_clear); + REG_WR_IND(bp, cpu_reg->mode, val); +} + +static void +bnx2_init_cpus(struct bnx2 *bp) +{ + struct cpu_reg cpu_reg; + struct fw_info fw; + + /* Initialize the RV2P processor. */ + load_rv2p_fw(bp, bnx2_rv2p_proc1, sizeof(bnx2_rv2p_proc1), RV2P_PROC1); + load_rv2p_fw(bp, bnx2_rv2p_proc2, sizeof(bnx2_rv2p_proc2), RV2P_PROC2); + + /* Initialize the RX Processor. */ + cpu_reg.mode = BNX2_RXP_CPU_MODE; + cpu_reg.mode_value_halt = BNX2_RXP_CPU_MODE_SOFT_HALT; + cpu_reg.mode_value_sstep = BNX2_RXP_CPU_MODE_STEP_ENA; + cpu_reg.state = BNX2_RXP_CPU_STATE; + cpu_reg.state_value_clear = 0xffffff; + cpu_reg.gpr0 = BNX2_RXP_CPU_REG_FILE; + cpu_reg.evmask = BNX2_RXP_CPU_EVENT_MASK; + cpu_reg.pc = BNX2_RXP_CPU_PROGRAM_COUNTER; + cpu_reg.inst = BNX2_RXP_CPU_INSTRUCTION; + cpu_reg.bp = BNX2_RXP_CPU_HW_BREAKPOINT; + cpu_reg.spad_base = BNX2_RXP_SCRATCH; + cpu_reg.mips_view_base = 0x8000000; + + fw.ver_major = bnx2_RXP_b06FwReleaseMajor; + fw.ver_minor = bnx2_RXP_b06FwReleaseMinor; + fw.ver_fix = bnx2_RXP_b06FwReleaseFix; + fw.start_addr = bnx2_RXP_b06FwStartAddr; + + fw.text_addr = bnx2_RXP_b06FwTextAddr; + fw.text_len = bnx2_RXP_b06FwTextLen; + fw.text_index = 0; + fw.text = bnx2_RXP_b06FwText; + + fw.data_addr = bnx2_RXP_b06FwDataAddr; + fw.data_len = bnx2_RXP_b06FwDataLen; + fw.data_index = 0; + fw.data = bnx2_RXP_b06FwData; + + fw.sbss_addr = bnx2_RXP_b06FwSbssAddr; + fw.sbss_len = bnx2_RXP_b06FwSbssLen; + fw.sbss_index = 0; + fw.sbss = bnx2_RXP_b06FwSbss; + + fw.bss_addr = bnx2_RXP_b06FwBssAddr; + fw.bss_len = bnx2_RXP_b06FwBssLen; + fw.bss_index = 0; + fw.bss = bnx2_RXP_b06FwBss; + + fw.rodata_addr = bnx2_RXP_b06FwRodataAddr; + fw.rodata_len = bnx2_RXP_b06FwRodataLen; + fw.rodata_index = 0; + fw.rodata = bnx2_RXP_b06FwRodata; + + load_cpu_fw(bp, &cpu_reg, &fw); + + /* Initialize the TX Processor. */ + cpu_reg.mode = BNX2_TXP_CPU_MODE; + cpu_reg.mode_value_halt = BNX2_TXP_CPU_MODE_SOFT_HALT; + cpu_reg.mode_value_sstep = BNX2_TXP_CPU_MODE_STEP_ENA; + cpu_reg.state = BNX2_TXP_CPU_STATE; + cpu_reg.state_value_clear = 0xffffff; + cpu_reg.gpr0 = BNX2_TXP_CPU_REG_FILE; + cpu_reg.evmask = BNX2_TXP_CPU_EVENT_MASK; + cpu_reg.pc = BNX2_TXP_CPU_PROGRAM_COUNTER; + cpu_reg.inst = BNX2_TXP_CPU_INSTRUCTION; + cpu_reg.bp = BNX2_TXP_CPU_HW_BREAKPOINT; + cpu_reg.spad_base = BNX2_TXP_SCRATCH; + cpu_reg.mips_view_base = 0x8000000; + + fw.ver_major = bnx2_TXP_b06FwReleaseMajor; + fw.ver_minor = bnx2_TXP_b06FwReleaseMinor; + fw.ver_fix = bnx2_TXP_b06FwReleaseFix; + fw.start_addr = bnx2_TXP_b06FwStartAddr; + + fw.text_addr = bnx2_TXP_b06FwTextAddr; + fw.text_len = bnx2_TXP_b06FwTextLen; + fw.text_index = 0; + fw.text = bnx2_TXP_b06FwText; + + fw.data_addr = bnx2_TXP_b06FwDataAddr; + fw.data_len = bnx2_TXP_b06FwDataLen; + fw.data_index = 0; + fw.data = bnx2_TXP_b06FwData; + + fw.sbss_addr = bnx2_TXP_b06FwSbssAddr; + fw.sbss_len = bnx2_TXP_b06FwSbssLen; + fw.sbss_index = 0; + fw.sbss = bnx2_TXP_b06FwSbss; + + fw.bss_addr = bnx2_TXP_b06FwBssAddr; + fw.bss_len = bnx2_TXP_b06FwBssLen; + fw.bss_index = 0; + fw.bss = bnx2_TXP_b06FwBss; + + fw.rodata_addr = bnx2_TXP_b06FwRodataAddr; + fw.rodata_len = bnx2_TXP_b06FwRodataLen; + fw.rodata_index = 0; + fw.rodata = bnx2_TXP_b06FwRodata; + + load_cpu_fw(bp, &cpu_reg, &fw); + + /* Initialize the TX Patch-up Processor. */ + cpu_reg.mode = BNX2_TPAT_CPU_MODE; + cpu_reg.mode_value_halt = BNX2_TPAT_CPU_MODE_SOFT_HALT; + cpu_reg.mode_value_sstep = BNX2_TPAT_CPU_MODE_STEP_ENA; + cpu_reg.state = BNX2_TPAT_CPU_STATE; + cpu_reg.state_value_clear = 0xffffff; + cpu_reg.gpr0 = BNX2_TPAT_CPU_REG_FILE; + cpu_reg.evmask = BNX2_TPAT_CPU_EVENT_MASK; + cpu_reg.pc = BNX2_TPAT_CPU_PROGRAM_COUNTER; + cpu_reg.inst = BNX2_TPAT_CPU_INSTRUCTION; + cpu_reg.bp = BNX2_TPAT_CPU_HW_BREAKPOINT; + cpu_reg.spad_base = BNX2_TPAT_SCRATCH; + cpu_reg.mips_view_base = 0x8000000; + + fw.ver_major = bnx2_TPAT_b06FwReleaseMajor; + fw.ver_minor = bnx2_TPAT_b06FwReleaseMinor; + fw.ver_fix = bnx2_TPAT_b06FwReleaseFix; + fw.start_addr = bnx2_TPAT_b06FwStartAddr; + + fw.text_addr = bnx2_TPAT_b06FwTextAddr; + fw.text_len = bnx2_TPAT_b06FwTextLen; + fw.text_index = 0; + fw.text = bnx2_TPAT_b06FwText; + + fw.data_addr = bnx2_TPAT_b06FwDataAddr; + fw.data_len = bnx2_TPAT_b06FwDataLen; + fw.data_index = 0; + fw.data = bnx2_TPAT_b06FwData; + + fw.sbss_addr = bnx2_TPAT_b06FwSbssAddr; + fw.sbss_len = bnx2_TPAT_b06FwSbssLen; + fw.sbss_index = 0; + fw.sbss = bnx2_TPAT_b06FwSbss; + + fw.bss_addr = bnx2_TPAT_b06FwBssAddr; + fw.bss_len = bnx2_TPAT_b06FwBssLen; + fw.bss_index = 0; + fw.bss = bnx2_TPAT_b06FwBss; + + fw.rodata_addr = bnx2_TPAT_b06FwRodataAddr; + fw.rodata_len = bnx2_TPAT_b06FwRodataLen; + fw.rodata_index = 0; + fw.rodata = bnx2_TPAT_b06FwRodata; + + load_cpu_fw(bp, &cpu_reg, &fw); + + /* Initialize the Completion Processor. */ + cpu_reg.mode = BNX2_COM_CPU_MODE; + cpu_reg.mode_value_halt = BNX2_COM_CPU_MODE_SOFT_HALT; + cpu_reg.mode_value_sstep = BNX2_COM_CPU_MODE_STEP_ENA; + cpu_reg.state = BNX2_COM_CPU_STATE; + cpu_reg.state_value_clear = 0xffffff; + cpu_reg.gpr0 = BNX2_COM_CPU_REG_FILE; + cpu_reg.evmask = BNX2_COM_CPU_EVENT_MASK; + cpu_reg.pc = BNX2_COM_CPU_PROGRAM_COUNTER; + cpu_reg.inst = BNX2_COM_CPU_INSTRUCTION; + cpu_reg.bp = BNX2_COM_CPU_HW_BREAKPOINT; + cpu_reg.spad_base = BNX2_COM_SCRATCH; + cpu_reg.mips_view_base = 0x8000000; + + fw.ver_major = bnx2_COM_b06FwReleaseMajor; + fw.ver_minor = bnx2_COM_b06FwReleaseMinor; + fw.ver_fix = bnx2_COM_b06FwReleaseFix; + fw.start_addr = bnx2_COM_b06FwStartAddr; + + fw.text_addr = bnx2_COM_b06FwTextAddr; + fw.text_len = bnx2_COM_b06FwTextLen; + fw.text_index = 0; + fw.text = bnx2_COM_b06FwText; + + fw.data_addr = bnx2_COM_b06FwDataAddr; + fw.data_len = bnx2_COM_b06FwDataLen; + fw.data_index = 0; + fw.data = bnx2_COM_b06FwData; + + fw.sbss_addr = bnx2_COM_b06FwSbssAddr; + fw.sbss_len = bnx2_COM_b06FwSbssLen; + fw.sbss_index = 0; + fw.sbss = bnx2_COM_b06FwSbss; + + fw.bss_addr = bnx2_COM_b06FwBssAddr; + fw.bss_len = bnx2_COM_b06FwBssLen; + fw.bss_index = 0; + fw.bss = bnx2_COM_b06FwBss; + + fw.rodata_addr = bnx2_COM_b06FwRodataAddr; + fw.rodata_len = bnx2_COM_b06FwRodataLen; + fw.rodata_index = 0; + fw.rodata = bnx2_COM_b06FwRodata; + + load_cpu_fw(bp, &cpu_reg, &fw); + +} + +static int +bnx2_set_power_state(struct bnx2 *bp, int state) +{ + u16 pmcsr; + + pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, &pmcsr); + + switch (state) { + case 0: { + u32 val; + + pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, + (pmcsr & ~PCI_PM_CTRL_STATE_MASK) | + PCI_PM_CTRL_PME_STATUS); + + if (pmcsr & PCI_PM_CTRL_STATE_MASK) + /* delay required during transition out of D3hot */ + msleep(20); + + val = REG_RD(bp, BNX2_EMAC_MODE); + val |= BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD; + val &= ~BNX2_EMAC_MODE_MPKT; + REG_WR(bp, BNX2_EMAC_MODE, val); + + val = REG_RD(bp, BNX2_RPM_CONFIG); + val &= ~BNX2_RPM_CONFIG_ACPI_ENA; + REG_WR(bp, BNX2_RPM_CONFIG, val); + break; + } + case 3: { + int i; + u32 val, wol_msg; + + if (bp->wol) { + u32 advertising; + u8 autoneg; + + autoneg = bp->autoneg; + advertising = bp->advertising; + + bp->autoneg = AUTONEG_SPEED; + bp->advertising = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_Autoneg; + + bnx2_setup_copper_phy(bp); + + bp->autoneg = autoneg; + bp->advertising = advertising; + + bnx2_set_mac_addr(bp); + + val = REG_RD(bp, BNX2_EMAC_MODE); + + /* Enable port mode. */ + val &= ~BNX2_EMAC_MODE_PORT; + val |= BNX2_EMAC_MODE_PORT_MII | + BNX2_EMAC_MODE_MPKT_RCVD | + BNX2_EMAC_MODE_ACPI_RCVD | + BNX2_EMAC_MODE_FORCE_LINK | + BNX2_EMAC_MODE_MPKT; + + REG_WR(bp, BNX2_EMAC_MODE, val); + + /* receive all multicast */ + for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { + REG_WR(bp, BNX2_EMAC_MULTICAST_HASH0 + (i * 4), + 0xffffffff); + } + REG_WR(bp, BNX2_EMAC_RX_MODE, + BNX2_EMAC_RX_MODE_SORT_MODE); + + val = 1 | BNX2_RPM_SORT_USER0_BC_EN | + BNX2_RPM_SORT_USER0_MC_EN; + REG_WR(bp, BNX2_RPM_SORT_USER0, 0x0); + REG_WR(bp, BNX2_RPM_SORT_USER0, val); + REG_WR(bp, BNX2_RPM_SORT_USER0, val | + BNX2_RPM_SORT_USER0_ENA); + + /* Need to enable EMAC and RPM for WOL. */ + REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, + BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE | + BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE | + BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE); + + val = REG_RD(bp, BNX2_RPM_CONFIG); + val &= ~BNX2_RPM_CONFIG_ACPI_ENA; + REG_WR(bp, BNX2_RPM_CONFIG, val); + + wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_WOL; + } + else { + wol_msg = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; + } + + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT3 | wol_msg); + + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || + (CHIP_ID(bp) == CHIP_ID_5706_A1)) { + + if (bp->wol) + pmcsr |= 3; + } + else { + pmcsr |= 3; + } + if (bp->wol) { + pmcsr |= PCI_PM_CTRL_PME_ENABLE; + } + pci_write_config_word(bp->pdev, bp->pm_cap + PCI_PM_CTRL, + pmcsr); + + /* No more memory access after this point until + * device is brought back to D0. + */ + udelay(50); + break; + } + default: + return -EINVAL; + } + return 0; +} + +static int +bnx2_acquire_nvram_lock(struct bnx2 *bp) +{ + u32 val; + int j; + + /* Request access to the flash interface. */ + REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_SET2); + for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { + val = REG_RD(bp, BNX2_NVM_SW_ARB); + if (val & BNX2_NVM_SW_ARB_ARB_ARB2) + break; + + udelay(5); + } + + if (j >= NVRAM_TIMEOUT_COUNT) + return -EBUSY; + + return 0; +} + +static int +bnx2_release_nvram_lock(struct bnx2 *bp) +{ + int j; + u32 val; + + /* Relinquish nvram interface. */ + REG_WR(bp, BNX2_NVM_SW_ARB, BNX2_NVM_SW_ARB_ARB_REQ_CLR2); + + for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { + val = REG_RD(bp, BNX2_NVM_SW_ARB); + if (!(val & BNX2_NVM_SW_ARB_ARB_ARB2)) + break; + + udelay(5); + } + + if (j >= NVRAM_TIMEOUT_COUNT) + return -EBUSY; + + return 0; +} + + +static int +bnx2_enable_nvram_write(struct bnx2 *bp) +{ + u32 val; + + val = REG_RD(bp, BNX2_MISC_CFG); + REG_WR(bp, BNX2_MISC_CFG, val | BNX2_MISC_CFG_NVM_WR_EN_PCI); + + if (!bp->flash_info->buffered) { + int j; + + REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE); + REG_WR(bp, BNX2_NVM_COMMAND, + BNX2_NVM_COMMAND_WREN | BNX2_NVM_COMMAND_DOIT); + + for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { + udelay(5); + + val = REG_RD(bp, BNX2_NVM_COMMAND); + if (val & BNX2_NVM_COMMAND_DONE) + break; + } + + if (j >= NVRAM_TIMEOUT_COUNT) + return -EBUSY; + } + return 0; +} + +static void +bnx2_disable_nvram_write(struct bnx2 *bp) +{ + u32 val; + + val = REG_RD(bp, BNX2_MISC_CFG); + REG_WR(bp, BNX2_MISC_CFG, val & ~BNX2_MISC_CFG_NVM_WR_EN); +} + + +static void +bnx2_enable_nvram_access(struct bnx2 *bp) +{ + u32 val; + + val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE); + /* Enable both bits, even on read. */ + REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, + val | BNX2_NVM_ACCESS_ENABLE_EN | BNX2_NVM_ACCESS_ENABLE_WR_EN); +} + +static void +bnx2_disable_nvram_access(struct bnx2 *bp) +{ + u32 val; + + val = REG_RD(bp, BNX2_NVM_ACCESS_ENABLE); + /* Disable both bits, even after read. */ + REG_WR(bp, BNX2_NVM_ACCESS_ENABLE, + val & ~(BNX2_NVM_ACCESS_ENABLE_EN | + BNX2_NVM_ACCESS_ENABLE_WR_EN)); +} + +static int +bnx2_nvram_erase_page(struct bnx2 *bp, u32 offset) +{ + u32 cmd; + int j; + + if (bp->flash_info->buffered) + /* Buffered flash, no erase needed */ + return 0; + + /* Build an erase command */ + cmd = BNX2_NVM_COMMAND_ERASE | BNX2_NVM_COMMAND_WR | + BNX2_NVM_COMMAND_DOIT; + + /* Need to clear DONE bit separately. */ + REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE); + + /* Address of the NVRAM to read from. */ + REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE); + + /* Issue an erase command. */ + REG_WR(bp, BNX2_NVM_COMMAND, cmd); + + /* Wait for completion. */ + for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { + u32 val; + + udelay(5); + + val = REG_RD(bp, BNX2_NVM_COMMAND); + if (val & BNX2_NVM_COMMAND_DONE) + break; + } + + if (j >= NVRAM_TIMEOUT_COUNT) + return -EBUSY; + + return 0; +} + +static int +bnx2_nvram_read_dword(struct bnx2 *bp, u32 offset, u8 *ret_val, u32 cmd_flags) +{ + u32 cmd; + int j; + + /* Build the command word. */ + cmd = BNX2_NVM_COMMAND_DOIT | cmd_flags; + + /* Calculate an offset of a buffered flash. */ + if (bp->flash_info->buffered) { + offset = ((offset / bp->flash_info->page_size) << + bp->flash_info->page_bits) + + (offset % bp->flash_info->page_size); + } + + /* Need to clear DONE bit separately. */ + REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE); + + /* Address of the NVRAM to read from. */ + REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE); + + /* Issue a read command. */ + REG_WR(bp, BNX2_NVM_COMMAND, cmd); + + /* Wait for completion. */ + for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { + u32 val; + + udelay(5); + + val = REG_RD(bp, BNX2_NVM_COMMAND); + if (val & BNX2_NVM_COMMAND_DONE) { + val = REG_RD(bp, BNX2_NVM_READ); + + val = be32_to_cpu(val); + memcpy(ret_val, &val, 4); + break; + } + } + if (j >= NVRAM_TIMEOUT_COUNT) + return -EBUSY; + + return 0; +} + + +static int +bnx2_nvram_write_dword(struct bnx2 *bp, u32 offset, u8 *val, u32 cmd_flags) +{ + u32 cmd, val32; + int j; + + /* Build the command word. */ + cmd = BNX2_NVM_COMMAND_DOIT | BNX2_NVM_COMMAND_WR | cmd_flags; + + /* Calculate an offset of a buffered flash. */ + if (bp->flash_info->buffered) { + offset = ((offset / bp->flash_info->page_size) << + bp->flash_info->page_bits) + + (offset % bp->flash_info->page_size); + } + + /* Need to clear DONE bit separately. */ + REG_WR(bp, BNX2_NVM_COMMAND, BNX2_NVM_COMMAND_DONE); + + memcpy(&val32, val, 4); + val32 = cpu_to_be32(val32); + + /* Write the data. */ + REG_WR(bp, BNX2_NVM_WRITE, val32); + + /* Address of the NVRAM to write to. */ + REG_WR(bp, BNX2_NVM_ADDR, offset & BNX2_NVM_ADDR_NVM_ADDR_VALUE); + + /* Issue the write command. */ + REG_WR(bp, BNX2_NVM_COMMAND, cmd); + + /* Wait for completion. */ + for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { + udelay(5); + + if (REG_RD(bp, BNX2_NVM_COMMAND) & BNX2_NVM_COMMAND_DONE) + break; + } + if (j >= NVRAM_TIMEOUT_COUNT) + return -EBUSY; + + return 0; +} + +static int +bnx2_init_nvram(struct bnx2 *bp) +{ + u32 val; + int j, entry_count, rc; + struct flash_spec *flash; + + /* Determine the selected interface. */ + val = REG_RD(bp, BNX2_NVM_CFG1); + + entry_count = sizeof(flash_table) / sizeof(struct flash_spec); + + rc = 0; + if (val & 0x40000000) { + + /* Flash interface has been reconfigured */ + for (j = 0, flash = &flash_table[0]; j < entry_count; + j++, flash++) { + + if (val == flash->config1) { + bp->flash_info = flash; + break; + } + } + } + else { + /* Not yet been reconfigured */ + + for (j = 0, flash = &flash_table[0]; j < entry_count; + j++, flash++) { + + if ((val & FLASH_STRAP_MASK) == flash->strapping) { + bp->flash_info = flash; + + /* Request access to the flash interface. */ + if ((rc = bnx2_acquire_nvram_lock(bp)) != 0) + return rc; + + /* Enable access to flash interface */ + bnx2_enable_nvram_access(bp); + + /* Reconfigure the flash interface */ + REG_WR(bp, BNX2_NVM_CFG1, flash->config1); + REG_WR(bp, BNX2_NVM_CFG2, flash->config2); + REG_WR(bp, BNX2_NVM_CFG3, flash->config3); + REG_WR(bp, BNX2_NVM_WRITE1, flash->write1); + + /* Disable access to flash interface */ + bnx2_disable_nvram_access(bp); + bnx2_release_nvram_lock(bp); + + break; + } + } + } /* if (val & 0x40000000) */ + + if (j == entry_count) { + bp->flash_info = NULL; + printk(KERN_ALERT "Unknown flash/EEPROM type.\n"); + rc = -ENODEV; + } + + return rc; +} + +static int +bnx2_nvram_read(struct bnx2 *bp, u32 offset, u8 *ret_buf, + int buf_size) +{ + int rc = 0; + u32 cmd_flags, offset32, len32, extra; + + if (buf_size == 0) + return 0; + + /* Request access to the flash interface. */ + if ((rc = bnx2_acquire_nvram_lock(bp)) != 0) + return rc; + + /* Enable access to flash interface */ + bnx2_enable_nvram_access(bp); + + len32 = buf_size; + offset32 = offset; + extra = 0; + + cmd_flags = 0; + + if (offset32 & 3) { + u8 buf[4]; + u32 pre_len; + + offset32 &= ~3; + pre_len = 4 - (offset & 3); + + if (pre_len >= len32) { + pre_len = len32; + cmd_flags = BNX2_NVM_COMMAND_FIRST | + BNX2_NVM_COMMAND_LAST; + } + else { + cmd_flags = BNX2_NVM_COMMAND_FIRST; + } + + rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags); + + if (rc) + return rc; + + memcpy(ret_buf, buf + (offset & 3), pre_len); + + offset32 += 4; + ret_buf += pre_len; + len32 -= pre_len; + } + if (len32 & 3) { + extra = 4 - (len32 & 3); + len32 = (len32 + 4) & ~3; + } + + if (len32 == 4) { + u8 buf[4]; + + if (cmd_flags) + cmd_flags = BNX2_NVM_COMMAND_LAST; + else + cmd_flags = BNX2_NVM_COMMAND_FIRST | + BNX2_NVM_COMMAND_LAST; + + rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags); + + memcpy(ret_buf, buf, 4 - extra); + } + else if (len32 > 0) { + u8 buf[4]; + + /* Read the first word. */ + if (cmd_flags) + cmd_flags = 0; + else + cmd_flags = BNX2_NVM_COMMAND_FIRST; + + rc = bnx2_nvram_read_dword(bp, offset32, ret_buf, cmd_flags); + + /* Advance to the next dword. */ + offset32 += 4; + ret_buf += 4; + len32 -= 4; + + while (len32 > 4 && rc == 0) { + rc = bnx2_nvram_read_dword(bp, offset32, ret_buf, 0); + + /* Advance to the next dword. */ + offset32 += 4; + ret_buf += 4; + len32 -= 4; + } + + if (rc) + return rc; + + cmd_flags = BNX2_NVM_COMMAND_LAST; + rc = bnx2_nvram_read_dword(bp, offset32, buf, cmd_flags); + + memcpy(ret_buf, buf, 4 - extra); + } + + /* Disable access to flash interface */ + bnx2_disable_nvram_access(bp); + + bnx2_release_nvram_lock(bp); + + return rc; +} + +static int +bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, + int buf_size) +{ + u32 written, offset32, len32; + u8 *buf, start[4], end[4]; + int rc = 0; + int align_start, align_end; + + buf = data_buf; + offset32 = offset; + len32 = buf_size; + align_start = align_end = 0; + + if ((align_start = (offset32 & 3))) { + offset32 &= ~3; + len32 += align_start; + if ((rc = bnx2_nvram_read(bp, offset32, start, 4))) + return rc; + } + + if (len32 & 3) { + if ((len32 > 4) || !align_start) { + align_end = 4 - (len32 & 3); + len32 += align_end; + if ((rc = bnx2_nvram_read(bp, offset32 + len32 - 4, + end, 4))) { + return rc; + } + } + } + + if (align_start || align_end) { + buf = kmalloc(len32, GFP_KERNEL); + if (buf == 0) + return -ENOMEM; + if (align_start) { + memcpy(buf, start, 4); + } + if (align_end) { + memcpy(buf + len32 - 4, end, 4); + } + memcpy(buf + align_start, data_buf, buf_size); + } + + written = 0; + while ((written < len32) && (rc == 0)) { + u32 page_start, page_end, data_start, data_end; + u32 addr, cmd_flags; + int i; + u8 flash_buffer[264]; + + /* Find the page_start addr */ + page_start = offset32 + written; + page_start -= (page_start % bp->flash_info->page_size); + /* Find the page_end addr */ + page_end = page_start + bp->flash_info->page_size; + /* Find the data_start addr */ + data_start = (written == 0) ? offset32 : page_start; + /* Find the data_end addr */ + data_end = (page_end > offset32 + len32) ? + (offset32 + len32) : page_end; + + /* Request access to the flash interface. */ + if ((rc = bnx2_acquire_nvram_lock(bp)) != 0) + goto nvram_write_end; + + /* Enable access to flash interface */ + bnx2_enable_nvram_access(bp); + + cmd_flags = BNX2_NVM_COMMAND_FIRST; + if (bp->flash_info->buffered == 0) { + int j; + + /* Read the whole page into the buffer + * (non-buffer flash only) */ + for (j = 0; j < bp->flash_info->page_size; j += 4) { + if (j == (bp->flash_info->page_size - 4)) { + cmd_flags |= BNX2_NVM_COMMAND_LAST; + } + rc = bnx2_nvram_read_dword(bp, + page_start + j, + &flash_buffer[j], + cmd_flags); + + if (rc) + goto nvram_write_end; + + cmd_flags = 0; + } + } + + /* Enable writes to flash interface (unlock write-protect) */ + if ((rc = bnx2_enable_nvram_write(bp)) != 0) + goto nvram_write_end; + + /* Erase the page */ + if ((rc = bnx2_nvram_erase_page(bp, page_start)) != 0) + goto nvram_write_end; + + /* Re-enable the write again for the actual write */ + bnx2_enable_nvram_write(bp); + + /* Loop to write back the buffer data from page_start to + * data_start */ + i = 0; + if (bp->flash_info->buffered == 0) { + for (addr = page_start; addr < data_start; + addr += 4, i += 4) { + + rc = bnx2_nvram_write_dword(bp, addr, + &flash_buffer[i], cmd_flags); + + if (rc != 0) + goto nvram_write_end; + + cmd_flags = 0; + } + } + + /* Loop to write the new data from data_start to data_end */ + for (addr = data_start; addr < data_end; addr += 4, i++) { + if ((addr == page_end - 4) || + ((bp->flash_info->buffered) && + (addr == data_end - 4))) { + + cmd_flags |= BNX2_NVM_COMMAND_LAST; + } + rc = bnx2_nvram_write_dword(bp, addr, buf, + cmd_flags); + + if (rc != 0) + goto nvram_write_end; + + cmd_flags = 0; + buf += 4; + } + + /* Loop to write back the buffer data from data_end + * to page_end */ + if (bp->flash_info->buffered == 0) { + for (addr = data_end; addr < page_end; + addr += 4, i += 4) { + + if (addr == page_end-4) { + cmd_flags = BNX2_NVM_COMMAND_LAST; + } + rc = bnx2_nvram_write_dword(bp, addr, + &flash_buffer[i], cmd_flags); + + if (rc != 0) + goto nvram_write_end; + + cmd_flags = 0; + } + } + + /* Disable writes to flash interface (lock write-protect) */ + bnx2_disable_nvram_write(bp); + + /* Disable access to flash interface */ + bnx2_disable_nvram_access(bp); + bnx2_release_nvram_lock(bp); + + /* Increment written */ + written += data_end - data_start; + } + +nvram_write_end: + if (align_start || align_end) + kfree(buf); + return rc; +} + +static int +bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) +{ + u32 val; + int i, rc = 0; + + /* Wait for the current PCI transaction to complete before + * issuing a reset. */ + REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, + BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | + BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); + val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); + udelay(5); + + /* Deposit a driver reset signature so the firmware knows that + * this is a soft reset. */ + REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE, + BNX2_DRV_RESET_SIGNATURE_MAGIC); + + bp->fw_timed_out = 0; + + /* Wait for the firmware to tell us it is ok to issue a reset. */ + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code); + + /* Do a dummy read to force the chip to complete all current transaction + * before we issue a reset. */ + val = REG_RD(bp, BNX2_MISC_ID); + + val = BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | + BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | + BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; + + /* Chip reset. */ + REG_WR(bp, BNX2_PCICFG_MISC_CONFIG, val); + + if ((CHIP_ID(bp) == CHIP_ID_5706_A0) || + (CHIP_ID(bp) == CHIP_ID_5706_A1)) + msleep(15); + + /* Reset takes approximate 30 usec */ + for (i = 0; i < 10; i++) { + val = REG_RD(bp, BNX2_PCICFG_MISC_CONFIG); + if ((val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | + BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) { + break; + } + udelay(10); + } + + if (val & (BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ | + BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY)) { + printk(KERN_ERR PFX "Chip reset did not complete\n"); + return -EBUSY; + } + + /* Make sure byte swapping is properly configured. */ + val = REG_RD(bp, BNX2_PCI_SWAP_DIAG0); + if (val != 0x01020304) { + printk(KERN_ERR PFX "Chip not in correct endian mode\n"); + return -ENODEV; + } + + bp->fw_timed_out = 0; + + /* Wait for the firmware to finish its initialization. */ + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT1 | reset_code); + + if (CHIP_ID(bp) == CHIP_ID_5706_A0) { + /* Adjust the voltage regular to two steps lower. The default + * of this register is 0x0000000e. */ + REG_WR(bp, BNX2_MISC_VREG_CONTROL, 0x000000fa); + + /* Remove bad rbuf memory from the free pool. */ + rc = bnx2_alloc_bad_rbuf(bp); + } + + return rc; +} + +static int +bnx2_init_chip(struct bnx2 *bp) +{ + u32 val; + + /* Make sure the interrupt is not active. */ + REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD, BNX2_PCICFG_INT_ACK_CMD_MASK_INT); + + val = BNX2_DMA_CONFIG_DATA_BYTE_SWAP | + BNX2_DMA_CONFIG_DATA_WORD_SWAP | +#ifdef __BIG_ENDIAN + BNX2_DMA_CONFIG_CNTL_BYTE_SWAP | +#endif + BNX2_DMA_CONFIG_CNTL_WORD_SWAP | + DMA_READ_CHANS << 12 | + DMA_WRITE_CHANS << 16; + + val |= (0x2 << 20) | (1 << 11); + + if ((bp->flags & PCIX_FLAG) && (bp->bus_speed_mhz = 133)) + val |= (1 << 23); + + if ((CHIP_NUM(bp) == CHIP_NUM_5706) && + (CHIP_ID(bp) != CHIP_ID_5706_A0) && !(bp->flags & PCIX_FLAG)) + val |= BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA; + + REG_WR(bp, BNX2_DMA_CONFIG, val); + + if (CHIP_ID(bp) == CHIP_ID_5706_A0) { + val = REG_RD(bp, BNX2_TDMA_CONFIG); + val |= BNX2_TDMA_CONFIG_ONE_DMA; + REG_WR(bp, BNX2_TDMA_CONFIG, val); + } + + if (bp->flags & PCIX_FLAG) { + u16 val16; + + pci_read_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD, + &val16); + pci_write_config_word(bp->pdev, bp->pcix_cap + PCI_X_CMD, + val16 & ~PCI_X_CMD_ERO); + } + + REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, + BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE | + BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE | + BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE); + + /* Initialize context mapping and zero out the quick contexts. The + * context block must have already been enabled. */ + bnx2_init_context(bp); + + bnx2_init_cpus(bp); + bnx2_init_nvram(bp); + + bnx2_set_mac_addr(bp); + + val = REG_RD(bp, BNX2_MQ_CONFIG); + val &= ~BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE; + val |= BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256; + REG_WR(bp, BNX2_MQ_CONFIG, val); + + val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE); + REG_WR(bp, BNX2_MQ_KNL_BYP_WIND_START, val); + REG_WR(bp, BNX2_MQ_KNL_WIND_END, val); + + val = (BCM_PAGE_BITS - 8) << 24; + REG_WR(bp, BNX2_RV2P_CONFIG, val); + + /* Configure page size. */ + val = REG_RD(bp, BNX2_TBDR_CONFIG); + val &= ~BNX2_TBDR_CONFIG_PAGE_SIZE; + val |= (BCM_PAGE_BITS - 8) << 24 | 0x40; + REG_WR(bp, BNX2_TBDR_CONFIG, val); + + val = bp->mac_addr[0] + + (bp->mac_addr[1] << 8) + + (bp->mac_addr[2] << 16) + + bp->mac_addr[3] + + (bp->mac_addr[4] << 8) + + (bp->mac_addr[5] << 16); + REG_WR(bp, BNX2_EMAC_BACKOFF_SEED, val); + + /* Program the MTU. Also include 4 bytes for CRC32. */ + val = bp->dev->mtu + ETH_HLEN + 4; + if (val > (MAX_ETHERNET_PACKET_SIZE + 4)) + val |= BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA; + REG_WR(bp, BNX2_EMAC_RX_MTU_SIZE, val); + + bp->last_status_idx = 0; + bp->rx_mode = BNX2_EMAC_RX_MODE_SORT_MODE; + + /* Set up how to generate a link change interrupt. */ + REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); + + REG_WR(bp, BNX2_HC_STATUS_ADDR_L, + (u64) bp->status_blk_mapping & 0xffffffff); + REG_WR(bp, BNX2_HC_STATUS_ADDR_H, (u64) bp->status_blk_mapping >> 32); + + REG_WR(bp, BNX2_HC_STATISTICS_ADDR_L, + (u64) bp->stats_blk_mapping & 0xffffffff); + REG_WR(bp, BNX2_HC_STATISTICS_ADDR_H, + (u64) bp->stats_blk_mapping >> 32); + + REG_WR(bp, BNX2_HC_TX_QUICK_CONS_TRIP, + (bp->tx_quick_cons_trip_int << 16) | bp->tx_quick_cons_trip); + + REG_WR(bp, BNX2_HC_RX_QUICK_CONS_TRIP, + (bp->rx_quick_cons_trip_int << 16) | bp->rx_quick_cons_trip); + + REG_WR(bp, BNX2_HC_COMP_PROD_TRIP, + (bp->comp_prod_trip_int << 16) | bp->comp_prod_trip); + + REG_WR(bp, BNX2_HC_TX_TICKS, (bp->tx_ticks_int << 16) | bp->tx_ticks); + + REG_WR(bp, BNX2_HC_RX_TICKS, (bp->rx_ticks_int << 16) | bp->rx_ticks); + + REG_WR(bp, BNX2_HC_COM_TICKS, + (bp->com_ticks_int << 16) | bp->com_ticks); + + REG_WR(bp, BNX2_HC_CMD_TICKS, + (bp->cmd_ticks_int << 16) | bp->cmd_ticks); + + REG_WR(bp, BNX2_HC_STATS_TICKS, bp->stats_ticks & 0xffff00); + REG_WR(bp, BNX2_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ + + if (CHIP_ID(bp) == CHIP_ID_5706_A1) + REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_COLLECT_STATS); + else { + REG_WR(bp, BNX2_HC_CONFIG, BNX2_HC_CONFIG_RX_TMR_MODE | + BNX2_HC_CONFIG_TX_TMR_MODE | + BNX2_HC_CONFIG_COLLECT_STATS); + } + + /* Clear internal stats counters. */ + REG_WR(bp, BNX2_HC_COMMAND, BNX2_HC_COMMAND_CLR_STAT_NOW); + + REG_WR(bp, BNX2_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE); + + /* Initialize the receive filter. */ + bnx2_set_rx_mode(bp->dev); + + bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT2 | BNX2_DRV_MSG_CODE_RESET); + + REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, 0x5ffffff); + REG_RD(bp, BNX2_MISC_ENABLE_SET_BITS); + + udelay(20); + + return 0; +} + + +static void +bnx2_init_tx_ring(struct bnx2 *bp) +{ + struct tx_bd *txbd; + u32 val; + + txbd = &bp->tx_desc_ring[MAX_TX_DESC_CNT]; + + txbd->tx_bd_haddr_hi = (u64) bp->tx_desc_mapping >> 32; + txbd->tx_bd_haddr_lo = (u64) bp->tx_desc_mapping & 0xffffffff; + + bp->tx_prod = 0; + bp->tx_cons = 0; + bp->tx_prod_bseq = 0; + atomic_set(&bp->tx_avail_bd, bp->tx_ring_size); + + val = BNX2_L2CTX_TYPE_TYPE_L2; + val |= BNX2_L2CTX_TYPE_SIZE_L2; + CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TYPE, val); + + val = BNX2_L2CTX_CMD_TYPE_TYPE_L2; + val |= 8 << 16; + CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_CMD_TYPE, val); + + val = (u64) bp->tx_desc_mapping >> 32; + CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_HI, val); + + val = (u64) bp->tx_desc_mapping & 0xffffffff; + CTX_WR(bp, GET_CID_ADDR(TX_CID), BNX2_L2CTX_TBDR_BHADDR_LO, val); +} + +static void +bnx2_init_rx_ring(struct bnx2 *bp) +{ + struct rx_bd *rxbd; + int i; + u16 prod, ring_prod; + u32 val; + + /* 8 for CRC and VLAN */ + bp->rx_buf_use_size = bp->dev->mtu + ETH_HLEN + bp->rx_offset + 8; + /* 8 for alignment */ + bp->rx_buf_size = bp->rx_buf_use_size + 8; + + ring_prod = prod = bp->rx_prod = 0; + bp->rx_cons = 0; + bp->rx_prod_bseq = 0; + + rxbd = &bp->rx_desc_ring[0]; + for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) { + rxbd->rx_bd_len = bp->rx_buf_use_size; + rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END; + } + + rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping >> 32; + rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff; + + val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE; + val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2; + val |= 0x02 << 8; + CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val); + + val = (u64) bp->rx_desc_mapping >> 32; + CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val); + + val = (u64) bp->rx_desc_mapping & 0xffffffff; + CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val); + + for ( ;ring_prod < bp->rx_ring_size; ) { + if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) { + break; + } + prod = NEXT_RX_BD(prod); + ring_prod = RX_RING_IDX(prod); + } + bp->rx_prod = prod; + + REG_WR16(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BDIDX, prod); + + REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq); +} + +static void +bnx2_free_tx_skbs(struct bnx2 *bp) +{ + int i; + + if (bp->tx_buf_ring == NULL) + return; + + for (i = 0; i < TX_DESC_CNT; ) { + struct sw_bd *tx_buf = &bp->tx_buf_ring[i]; + struct sk_buff *skb = tx_buf->skb; + int j, last; + + if (skb == NULL) { + i++; + continue; + } + + pci_unmap_single(bp->pdev, pci_unmap_addr(tx_buf, mapping), + skb_headlen(skb), PCI_DMA_TODEVICE); + + tx_buf->skb = NULL; + + last = skb_shinfo(skb)->nr_frags; + for (j = 0; j < last; j++) { + tx_buf = &bp->tx_buf_ring[i + j + 1]; + pci_unmap_page(bp->pdev, + pci_unmap_addr(tx_buf, mapping), + skb_shinfo(skb)->frags[j].size, + PCI_DMA_TODEVICE); + } + dev_kfree_skb_any(skb); + i += j + 1; + } + +} + +static void +bnx2_free_rx_skbs(struct bnx2 *bp) +{ + int i; + + if (bp->rx_buf_ring == NULL) + return; + + for (i = 0; i < RX_DESC_CNT; i++) { + struct sw_bd *rx_buf = &bp->rx_buf_ring[i]; + struct sk_buff *skb = rx_buf->skb; + + if (skb == 0) + continue; + + pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping), + bp->rx_buf_use_size, PCI_DMA_FROMDEVICE); + + rx_buf->skb = NULL; + + dev_kfree_skb_any(skb); + } +} + +static void +bnx2_free_skbs(struct bnx2 *bp) +{ + bnx2_free_tx_skbs(bp); + bnx2_free_rx_skbs(bp); +} + +static int +bnx2_reset_nic(struct bnx2 *bp, u32 reset_code) +{ + int rc; + + rc = bnx2_reset_chip(bp, reset_code); + bnx2_free_skbs(bp); + if (rc) + return rc; + + bnx2_init_chip(bp); + bnx2_init_tx_ring(bp); + bnx2_init_rx_ring(bp); + return 0; +} + +static int +bnx2_init_nic(struct bnx2 *bp) +{ + int rc; + + if ((rc = bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_RESET)) != 0) + return rc; + + bnx2_init_phy(bp); + bnx2_set_link(bp); + return 0; +} + +static int +bnx2_test_registers(struct bnx2 *bp) +{ + int ret; + int i; + static struct { + u16 offset; + u16 flags; + u32 rw_mask; + u32 ro_mask; + } reg_tbl[] = { + { 0x006c, 0, 0x00000000, 0x0000003f }, + { 0x0090, 0, 0xffffffff, 0x00000000 }, + { 0x0094, 0, 0x00000000, 0x00000000 }, + + { 0x0404, 0, 0x00003f00, 0x00000000 }, + { 0x0418, 0, 0x00000000, 0xffffffff }, + { 0x041c, 0, 0x00000000, 0xffffffff }, + { 0x0420, 0, 0x00000000, 0x80ffffff }, + { 0x0424, 0, 0x00000000, 0x00000000 }, + { 0x0428, 0, 0x00000000, 0x00000001 }, + { 0x0450, 0, 0x00000000, 0x0000ffff }, + { 0x0454, 0, 0x00000000, 0xffffffff }, + { 0x0458, 0, 0x00000000, 0xffffffff }, + + { 0x0808, 0, 0x00000000, 0xffffffff }, + { 0x0854, 0, 0x00000000, 0xffffffff }, + { 0x0868, 0, 0x00000000, 0x77777777 }, + { 0x086c, 0, 0x00000000, 0x77777777 }, + { 0x0870, 0, 0x00000000, 0x77777777 }, + { 0x0874, 0, 0x00000000, 0x77777777 }, + + { 0x0c00, 0, 0x00000000, 0x00000001 }, + { 0x0c04, 0, 0x00000000, 0x03ff0001 }, + { 0x0c08, 0, 0x0f0ff073, 0x00000000 }, + { 0x0c0c, 0, 0x00ffffff, 0x00000000 }, + { 0x0c30, 0, 0x00000000, 0xffffffff }, + { 0x0c34, 0, 0x00000000, 0xffffffff }, + { 0x0c38, 0, 0x00000000, 0xffffffff }, + { 0x0c3c, 0, 0x00000000, 0xffffffff }, + { 0x0c40, 0, 0x00000000, 0xffffffff }, + { 0x0c44, 0, 0x00000000, 0xffffffff }, + { 0x0c48, 0, 0x00000000, 0x0007ffff }, + { 0x0c4c, 0, 0x00000000, 0xffffffff }, + { 0x0c50, 0, 0x00000000, 0xffffffff }, + { 0x0c54, 0, 0x00000000, 0xffffffff }, + { 0x0c58, 0, 0x00000000, 0xffffffff }, + { 0x0c5c, 0, 0x00000000, 0xffffffff }, + { 0x0c60, 0, 0x00000000, 0xffffffff }, + { 0x0c64, 0, 0x00000000, 0xffffffff }, + { 0x0c68, 0, 0x00000000, 0xffffffff }, + { 0x0c6c, 0, 0x00000000, 0xffffffff }, + { 0x0c70, 0, 0x00000000, 0xffffffff }, + { 0x0c74, 0, 0x00000000, 0xffffffff }, + { 0x0c78, 0, 0x00000000, 0xffffffff }, + { 0x0c7c, 0, 0x00000000, 0xffffffff }, + { 0x0c80, 0, 0x00000000, 0xffffffff }, + { 0x0c84, 0, 0x00000000, 0xffffffff }, + { 0x0c88, 0, 0x00000000, 0xffffffff }, + { 0x0c8c, 0, 0x00000000, 0xffffffff }, + { 0x0c90, 0, 0x00000000, 0xffffffff }, + { 0x0c94, 0, 0x00000000, 0xffffffff }, + { 0x0c98, 0, 0x00000000, 0xffffffff }, + { 0x0c9c, 0, 0x00000000, 0xffffffff }, + { 0x0ca0, 0, 0x00000000, 0xffffffff }, + { 0x0ca4, 0, 0x00000000, 0xffffffff }, + { 0x0ca8, 0, 0x00000000, 0x0007ffff }, + { 0x0cac, 0, 0x00000000, 0xffffffff }, + { 0x0cb0, 0, 0x00000000, 0xffffffff }, + { 0x0cb4, 0, 0x00000000, 0xffffffff }, + { 0x0cb8, 0, 0x00000000, 0xffffffff }, + { 0x0cbc, 0, 0x00000000, 0xffffffff }, + { 0x0cc0, 0, 0x00000000, 0xffffffff }, + { 0x0cc4, 0, 0x00000000, 0xffffffff }, + { 0x0cc8, 0, 0x00000000, 0xffffffff }, + { 0x0ccc, 0, 0x00000000, 0xffffffff }, + { 0x0cd0, 0, 0x00000000, 0xffffffff }, + { 0x0cd4, 0, 0x00000000, 0xffffffff }, + { 0x0cd8, 0, 0x00000000, 0xffffffff }, + { 0x0cdc, 0, 0x00000000, 0xffffffff }, + { 0x0ce0, 0, 0x00000000, 0xffffffff }, + { 0x0ce4, 0, 0x00000000, 0xffffffff }, + { 0x0ce8, 0, 0x00000000, 0xffffffff }, + { 0x0cec, 0, 0x00000000, 0xffffffff }, + { 0x0cf0, 0, 0x00000000, 0xffffffff }, + { 0x0cf4, 0, 0x00000000, 0xffffffff }, + { 0x0cf8, 0, 0x00000000, 0xffffffff }, + { 0x0cfc, 0, 0x00000000, 0xffffffff }, + { 0x0d00, 0, 0x00000000, 0xffffffff }, + { 0x0d04, 0, 0x00000000, 0xffffffff }, + + { 0x1000, 0, 0x00000000, 0x00000001 }, + { 0x1004, 0, 0x00000000, 0x000f0001 }, + { 0x1044, 0, 0x00000000, 0xffc003ff }, + { 0x1080, 0, 0x00000000, 0x0001ffff }, + { 0x1084, 0, 0x00000000, 0xffffffff }, + { 0x1088, 0, 0x00000000, 0xffffffff }, + { 0x108c, 0, 0x00000000, 0xffffffff }, + { 0x1090, 0, 0x00000000, 0xffffffff }, + { 0x1094, 0, 0x00000000, 0xffffffff }, + { 0x1098, 0, 0x00000000, 0xffffffff }, + { 0x109c, 0, 0x00000000, 0xffffffff }, + { 0x10a0, 0, 0x00000000, 0xffffffff }, + + { 0x1408, 0, 0x01c00800, 0x00000000 }, + { 0x149c, 0, 0x8000ffff, 0x00000000 }, + { 0x14a8, 0, 0x00000000, 0x000001ff }, + { 0x14ac, 0, 0x4fffffff, 0x10000000 }, + { 0x14b0, 0, 0x00000002, 0x00000001 }, + { 0x14b8, 0, 0x00000000, 0x00000000 }, + { 0x14c0, 0, 0x00000000, 0x00000009 }, + { 0x14c4, 0, 0x00003fff, 0x00000000 }, + { 0x14cc, 0, 0x00000000, 0x00000001 }, + { 0x14d0, 0, 0xffffffff, 0x00000000 }, + { 0x1500, 0, 0x00000000, 0xffffffff }, + { 0x1504, 0, 0x00000000, 0xffffffff }, + { 0x1508, 0, 0x00000000, 0xffffffff }, + { 0x150c, 0, 0x00000000, 0xffffffff }, + { 0x1510, 0, 0x00000000, 0xffffffff }, + { 0x1514, 0, 0x00000000, 0xffffffff }, + { 0x1518, 0, 0x00000000, 0xffffffff }, + { 0x151c, 0, 0x00000000, 0xffffffff }, + { 0x1520, 0, 0x00000000, 0xffffffff }, + { 0x1524, 0, 0x00000000, 0xffffffff }, + { 0x1528, 0, 0x00000000, 0xffffffff }, + { 0x152c, 0, 0x00000000, 0xffffffff }, + { 0x1530, 0, 0x00000000, 0xffffffff }, + { 0x1534, 0, 0x00000000, 0xffffffff }, + { 0x1538, 0, 0x00000000, 0xffffffff }, + { 0x153c, 0, 0x00000000, 0xffffffff }, + { 0x1540, 0, 0x00000000, 0xffffffff }, + { 0x1544, 0, 0x00000000, 0xffffffff }, + { 0x1548, 0, 0x00000000, 0xffffffff }, + { 0x154c, 0, 0x00000000, 0xffffffff }, + { 0x1550, 0, 0x00000000, 0xffffffff }, + { 0x1554, 0, 0x00000000, 0xffffffff }, + { 0x1558, 0, 0x00000000, 0xffffffff }, + { 0x1600, 0, 0x00000000, 0xffffffff }, + { 0x1604, 0, 0x00000000, 0xffffffff }, + { 0x1608, 0, 0x00000000, 0xffffffff }, + { 0x160c, 0, 0x00000000, 0xffffffff }, + { 0x1610, 0, 0x00000000, 0xffffffff }, + { 0x1614, 0, 0x00000000, 0xffffffff }, + { 0x1618, 0, 0x00000000, 0xffffffff }, + { 0x161c, 0, 0x00000000, 0xffffffff }, + { 0x1620, 0, 0x00000000, 0xffffffff }, + { 0x1624, 0, 0x00000000, 0xffffffff }, + { 0x1628, 0, 0x00000000, 0xffffffff }, + { 0x162c, 0, 0x00000000, 0xffffffff }, + { 0x1630, 0, 0x00000000, 0xffffffff }, + { 0x1634, 0, 0x00000000, 0xffffffff }, + { 0x1638, 0, 0x00000000, 0xffffffff }, + { 0x163c, 0, 0x00000000, 0xffffffff }, + { 0x1640, 0, 0x00000000, 0xffffffff }, + { 0x1644, 0, 0x00000000, 0xffffffff }, + { 0x1648, 0, 0x00000000, 0xffffffff }, + { 0x164c, 0, 0x00000000, 0xffffffff }, + { 0x1650, 0, 0x00000000, 0xffffffff }, + { 0x1654, 0, 0x00000000, 0xffffffff }, + + { 0x1800, 0, 0x00000000, 0x00000001 }, + { 0x1804, 0, 0x00000000, 0x00000003 }, + { 0x1840, 0, 0x00000000, 0xffffffff }, + { 0x1844, 0, 0x00000000, 0xffffffff }, + { 0x1848, 0, 0x00000000, 0xffffffff }, + { 0x184c, 0, 0x00000000, 0xffffffff }, + { 0x1850, 0, 0x00000000, 0xffffffff }, + { 0x1900, 0, 0x7ffbffff, 0x00000000 }, + { 0x1904, 0, 0xffffffff, 0x00000000 }, + { 0x190c, 0, 0xffffffff, 0x00000000 }, + { 0x1914, 0, 0xffffffff, 0x00000000 }, + { 0x191c, 0, 0xffffffff, 0x00000000 }, + { 0x1924, 0, 0xffffffff, 0x00000000 }, + { 0x192c, 0, 0xffffffff, 0x00000000 }, + { 0x1934, 0, 0xffffffff, 0x00000000 }, + { 0x193c, 0, 0xffffffff, 0x00000000 }, + { 0x1944, 0, 0xffffffff, 0x00000000 }, + { 0x194c, 0, 0xffffffff, 0x00000000 }, + { 0x1954, 0, 0xffffffff, 0x00000000 }, + { 0x195c, 0, 0xffffffff, 0x00000000 }, + { 0x1964, 0, 0xffffffff, 0x00000000 }, + { 0x196c, 0, 0xffffffff, 0x00000000 }, + { 0x1974, 0, 0xffffffff, 0x00000000 }, + { 0x197c, 0, 0xffffffff, 0x00000000 }, + { 0x1980, 0, 0x0700ffff, 0x00000000 }, + + { 0x1c00, 0, 0x00000000, 0x00000001 }, + { 0x1c04, 0, 0x00000000, 0x00000003 }, + { 0x1c08, 0, 0x0000000f, 0x00000000 }, + { 0x1c40, 0, 0x00000000, 0xffffffff }, + { 0x1c44, 0, 0x00000000, 0xffffffff }, + { 0x1c48, 0, 0x00000000, 0xffffffff }, + { 0x1c4c, 0, 0x00000000, 0xffffffff }, + { 0x1c50, 0, 0x00000000, 0xffffffff }, + { 0x1d00, 0, 0x7ffbffff, 0x00000000 }, + { 0x1d04, 0, 0xffffffff, 0x00000000 }, + { 0x1d0c, 0, 0xffffffff, 0x00000000 }, + { 0x1d14, 0, 0xffffffff, 0x00000000 }, + { 0x1d1c, 0, 0xffffffff, 0x00000000 }, + { 0x1d24, 0, 0xffffffff, 0x00000000 }, + { 0x1d2c, 0, 0xffffffff, 0x00000000 }, + { 0x1d34, 0, 0xffffffff, 0x00000000 }, + { 0x1d3c, 0, 0xffffffff, 0x00000000 }, + { 0x1d44, 0, 0xffffffff, 0x00000000 }, + { 0x1d4c, 0, 0xffffffff, 0x00000000 }, + { 0x1d54, 0, 0xffffffff, 0x00000000 }, + { 0x1d5c, 0, 0xffffffff, 0x00000000 }, + { 0x1d64, 0, 0xffffffff, 0x00000000 }, + { 0x1d6c, 0, 0xffffffff, 0x00000000 }, + { 0x1d74, 0, 0xffffffff, 0x00000000 }, + { 0x1d7c, 0, 0xffffffff, 0x00000000 }, + { 0x1d80, 0, 0x0700ffff, 0x00000000 }, + + { 0x2004, 0, 0x00000000, 0x0337000f }, + { 0x2008, 0, 0xffffffff, 0x00000000 }, + { 0x200c, 0, 0xffffffff, 0x00000000 }, + { 0x2010, 0, 0xffffffff, 0x00000000 }, + { 0x2014, 0, 0x801fff80, 0x00000000 }, + { 0x2018, 0, 0x000003ff, 0x00000000 }, + + { 0x2800, 0, 0x00000000, 0x00000001 }, + { 0x2804, 0, 0x00000000, 0x00003f01 }, + { 0x2808, 0, 0x0f3f3f03, 0x00000000 }, + { 0x2810, 0, 0xffff0000, 0x00000000 }, + { 0x2814, 0, 0xffff0000, 0x00000000 }, + { 0x2818, 0, 0xffff0000, 0x00000000 }, + { 0x281c, 0, 0xffff0000, 0x00000000 }, + { 0x2834, 0, 0xffffffff, 0x00000000 }, + { 0x2840, 0, 0x00000000, 0xffffffff }, + { 0x2844, 0, 0x00000000, 0xffffffff }, + { 0x2848, 0, 0xffffffff, 0x00000000 }, + { 0x284c, 0, 0xf800f800, 0x07ff07ff }, + + { 0x2c00, 0, 0x00000000, 0x00000011 }, + { 0x2c04, 0, 0x00000000, 0x00030007 }, + + { 0x3000, 0, 0x00000000, 0x00000001 }, + { 0x3004, 0, 0x00000000, 0x007007ff }, + { 0x3008, 0, 0x00000003, 0x00000000 }, + { 0x300c, 0, 0xffffffff, 0x00000000 }, + { 0x3010, 0, 0xffffffff, 0x00000000 }, + { 0x3014, 0, 0xffffffff, 0x00000000 }, + { 0x3034, 0, 0xffffffff, 0x00000000 }, + { 0x3038, 0, 0xffffffff, 0x00000000 }, + { 0x3050, 0, 0x00000001, 0x00000000 }, + + { 0x3c00, 0, 0x00000000, 0x00000001 }, + { 0x3c04, 0, 0x00000000, 0x00070000 }, + { 0x3c08, 0, 0x00007f71, 0x07f00000 }, + { 0x3c0c, 0, 0x1f3ffffc, 0x00000000 }, + { 0x3c10, 0, 0xffffffff, 0x00000000 }, + { 0x3c14, 0, 0x00000000, 0xffffffff }, + { 0x3c18, 0, 0x00000000, 0xffffffff }, + { 0x3c1c, 0, 0xfffff000, 0x00000000 }, + { 0x3c20, 0, 0xffffff00, 0x00000000 }, + { 0x3c24, 0, 0xffffffff, 0x00000000 }, + { 0x3c28, 0, 0xffffffff, 0x00000000 }, + { 0x3c2c, 0, 0xffffffff, 0x00000000 }, + { 0x3c30, 0, 0xffffffff, 0x00000000 }, + { 0x3c34, 0, 0xffffffff, 0x00000000 }, + { 0x3c38, 0, 0xffffffff, 0x00000000 }, + { 0x3c3c, 0, 0xffffffff, 0x00000000 }, + { 0x3c40, 0, 0xffffffff, 0x00000000 }, + { 0x3c44, 0, 0xffffffff, 0x00000000 }, + { 0x3c48, 0, 0xffffffff, 0x00000000 }, + { 0x3c4c, 0, 0xffffffff, 0x00000000 }, + { 0x3c50, 0, 0xffffffff, 0x00000000 }, + { 0x3c54, 0, 0xffffffff, 0x00000000 }, + { 0x3c58, 0, 0xffffffff, 0x00000000 }, + { 0x3c5c, 0, 0xffffffff, 0x00000000 }, + { 0x3c60, 0, 0xffffffff, 0x00000000 }, + { 0x3c64, 0, 0xffffffff, 0x00000000 }, + { 0x3c68, 0, 0xffffffff, 0x00000000 }, + { 0x3c6c, 0, 0xffffffff, 0x00000000 }, + { 0x3c70, 0, 0xffffffff, 0x00000000 }, + { 0x3c74, 0, 0x0000003f, 0x00000000 }, + { 0x3c78, 0, 0x00000000, 0x00000000 }, + { 0x3c7c, 0, 0x00000000, 0x00000000 }, + { 0x3c80, 0, 0x3fffffff, 0x00000000 }, + { 0x3c84, 0, 0x0000003f, 0x00000000 }, + { 0x3c88, 0, 0x00000000, 0xffffffff }, + { 0x3c8c, 0, 0x00000000, 0xffffffff }, + + { 0x4000, 0, 0x00000000, 0x00000001 }, + { 0x4004, 0, 0x00000000, 0x00030000 }, + { 0x4008, 0, 0x00000ff0, 0x00000000 }, + { 0x400c, 0, 0xffffffff, 0x00000000 }, + { 0x4088, 0, 0x00000000, 0x00070303 }, + + { 0x4400, 0, 0x00000000, 0x00000001 }, + { 0x4404, 0, 0x00000000, 0x00003f01 }, + { 0x4408, 0, 0x7fff00ff, 0x00000000 }, + { 0x440c, 0, 0xffffffff, 0x00000000 }, + { 0x4410, 0, 0xffff, 0x0000 }, + { 0x4414, 0, 0xffff, 0x0000 }, + { 0x4418, 0, 0xffff, 0x0000 }, + { 0x441c, 0, 0xffff, 0x0000 }, + { 0x4428, 0, 0xffffffff, 0x00000000 }, + { 0x442c, 0, 0xffffffff, 0x00000000 }, + { 0x4430, 0, 0xffffffff, 0x00000000 }, + { 0x4434, 0, 0xffffffff, 0x00000000 }, + { 0x4438, 0, 0xffffffff, 0x00000000 }, + { 0x443c, 0, 0xffffffff, 0x00000000 }, + { 0x4440, 0, 0xffffffff, 0x00000000 }, + { 0x4444, 0, 0xffffffff, 0x00000000 }, + + { 0x4c00, 0, 0x00000000, 0x00000001 }, + { 0x4c04, 0, 0x00000000, 0x0000003f }, + { 0x4c08, 0, 0xffffffff, 0x00000000 }, + { 0x4c0c, 0, 0x0007fc00, 0x00000000 }, + { 0x4c10, 0, 0x80003fe0, 0x00000000 }, + { 0x4c14, 0, 0xffffffff, 0x00000000 }, + { 0x4c44, 0, 0x00000000, 0x9fff9fff }, + { 0x4c48, 0, 0x00000000, 0xb3009fff }, + { 0x4c4c, 0, 0x00000000, 0x77f33b30 }, + { 0x4c50, 0, 0x00000000, 0xffffffff }, + + { 0x5004, 0, 0x00000000, 0x0000007f }, + { 0x5008, 0, 0x0f0007ff, 0x00000000 }, + { 0x500c, 0, 0xf800f800, 0x07ff07ff }, + + { 0x5400, 0, 0x00000008, 0x00000001 }, + { 0x5404, 0, 0x00000000, 0x0000003f }, + { 0x5408, 0, 0x0000001f, 0x00000000 }, + { 0x540c, 0, 0xffffffff, 0x00000000 }, + { 0x5410, 0, 0xffffffff, 0x00000000 }, + { 0x5414, 0, 0x0000ffff, 0x00000000 }, + { 0x5418, 0, 0x0000ffff, 0x00000000 }, + { 0x541c, 0, 0x0000ffff, 0x00000000 }, + { 0x5420, 0, 0x0000ffff, 0x00000000 }, + { 0x5428, 0, 0x000000ff, 0x00000000 }, + { 0x542c, 0, 0xff00ffff, 0x00000000 }, + { 0x5430, 0, 0x001fff80, 0x00000000 }, + { 0x5438, 0, 0xffffffff, 0x00000000 }, + { 0x543c, 0, 0xffffffff, 0x00000000 }, + { 0x5440, 0, 0xf800f800, 0x07ff07ff }, + + { 0x5c00, 0, 0x00000000, 0x00000001 }, + { 0x5c04, 0, 0x00000000, 0x0003000f }, + { 0x5c08, 0, 0x00000003, 0x00000000 }, + { 0x5c0c, 0, 0x0000fff8, 0x00000000 }, + { 0x5c10, 0, 0x00000000, 0xffffffff }, + { 0x5c80, 0, 0x00000000, 0x0f7113f1 }, + { 0x5c84, 0, 0x00000000, 0x0000f333 }, + { 0x5c88, 0, 0x00000000, 0x00077373 }, + { 0x5c8c, 0, 0x00000000, 0x0007f737 }, + + { 0x6808, 0, 0x0000ff7f, 0x00000000 }, + { 0x680c, 0, 0xffffffff, 0x00000000 }, + { 0x6810, 0, 0xffffffff, 0x00000000 }, + { 0x6814, 0, 0xffffffff, 0x00000000 }, + { 0x6818, 0, 0xffffffff, 0x00000000 }, + { 0x681c, 0, 0xffffffff, 0x00000000 }, + { 0x6820, 0, 0x00ff00ff, 0x00000000 }, + { 0x6824, 0, 0x00ff00ff, 0x00000000 }, + { 0x6828, 0, 0x00ff00ff, 0x00000000 }, + { 0x682c, 0, 0x03ff03ff, 0x00000000 }, + { 0x6830, 0, 0x03ff03ff, 0x00000000 }, + { 0x6834, 0, 0x03ff03ff, 0x00000000 }, + { 0x6838, 0, 0x03ff03ff, 0x00000000 }, + { 0x683c, 0, 0x0000ffff, 0x00000000 }, + { 0x6840, 0, 0x00000ff0, 0x00000000 }, + { 0x6844, 0, 0x00ffff00, 0x00000000 }, + { 0x684c, 0, 0xffffffff, 0x00000000 }, + { 0x6850, 0, 0x7f7f7f7f, 0x00000000 }, + { 0x6854, 0, 0x7f7f7f7f, 0x00000000 }, + { 0x6858, 0, 0x7f7f7f7f, 0x00000000 }, + { 0x685c, 0, 0x7f7f7f7f, 0x00000000 }, + { 0x6908, 0, 0x00000000, 0x0001ff0f }, + { 0x690c, 0, 0x00000000, 0x0ffe00f0 }, + + { 0xffff, 0, 0x00000000, 0x00000000 }, + }; + + ret = 0; + for (i = 0; reg_tbl[i].offset != 0xffff; i++) { + u32 offset, rw_mask, ro_mask, save_val, val; + + offset = (u32) reg_tbl[i].offset; + rw_mask = reg_tbl[i].rw_mask; + ro_mask = reg_tbl[i].ro_mask; + + save_val = readl((u8 *) bp->regview + offset); + + writel(0, (u8 *) bp->regview + offset); + + val = readl((u8 *) bp->regview + offset); + if ((val & rw_mask) != 0) { + goto reg_test_err; + } + + if ((val & ro_mask) != (save_val & ro_mask)) { + goto reg_test_err; + } + + writel(0xffffffff, (u8 *) bp->regview + offset); + + val = readl((u8 *) bp->regview + offset); + if ((val & rw_mask) != rw_mask) { + goto reg_test_err; + } + + if ((val & ro_mask) != (save_val & ro_mask)) { + goto reg_test_err; + } + + writel(save_val, (u8 *) bp->regview + offset); + continue; + +reg_test_err: + writel(save_val, (u8 *) bp->regview + offset); + ret = -ENODEV; + break; + } + return ret; +} + +static int +bnx2_do_mem_test(struct bnx2 *bp, u32 start, u32 size) +{ + static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0x55555555, + 0xaaaaaaaa , 0xaa55aa55, 0x55aa55aa }; + int i; + + for (i = 0; i < sizeof(test_pattern) / 4; i++) { + u32 offset; + + for (offset = 0; offset < size; offset += 4) { + + REG_WR_IND(bp, start + offset, test_pattern[i]); + + if (REG_RD_IND(bp, start + offset) != + test_pattern[i]) { + return -ENODEV; + } + } + } + return 0; +} + +static int +bnx2_test_memory(struct bnx2 *bp) +{ + int ret = 0; + int i; + static struct { + u32 offset; + u32 len; + } mem_tbl[] = { + { 0x60000, 0x4000 }, + { 0xa0000, 0x4000 }, + { 0xe0000, 0x4000 }, + { 0x120000, 0x4000 }, + { 0x1a0000, 0x4000 }, + { 0x160000, 0x4000 }, + { 0xffffffff, 0 }, + }; + + for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { + if ((ret = bnx2_do_mem_test(bp, mem_tbl[i].offset, + mem_tbl[i].len)) != 0) { + return ret; + } + } + + return ret; +} + +static int +bnx2_test_loopback(struct bnx2 *bp) +{ + unsigned int pkt_size, num_pkts, i; + struct sk_buff *skb, *rx_skb; + unsigned char *packet; + u16 rx_start_idx, rx_idx, send_idx; + u32 send_bseq, val; + dma_addr_t map; + struct tx_bd *txbd; + struct sw_bd *rx_buf; + struct l2_fhdr *rx_hdr; + int ret = -ENODEV; + + if (!netif_running(bp->dev)) + return -ENODEV; + + bp->loopback = MAC_LOOPBACK; + bnx2_reset_nic(bp, BNX2_DRV_MSG_CODE_DIAG); + bnx2_set_mac_loopback(bp); + + pkt_size = 1514; + skb = dev_alloc_skb(pkt_size); + packet = skb_put(skb, pkt_size); + memcpy(packet, bp->mac_addr, 6); + memset(packet + 6, 0x0, 8); + for (i = 14; i < pkt_size; i++) + packet[i] = (unsigned char) (i & 0xff); + + map = pci_map_single(bp->pdev, skb->data, pkt_size, + PCI_DMA_TODEVICE); + + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); + REG_RD(bp, BNX2_HC_COMMAND); + + udelay(5); + rx_start_idx = bp->status_blk->status_rx_quick_consumer_index0; + + send_idx = 0; + send_bseq = 0; + num_pkts = 0; + + txbd = &bp->tx_desc_ring[send_idx]; + + txbd->tx_bd_haddr_hi = (u64) map >> 32; + txbd->tx_bd_haddr_lo = (u64) map & 0xffffffff; + txbd->tx_bd_mss_nbytes = pkt_size; + txbd->tx_bd_vlan_tag_flags = TX_BD_FLAGS_START | TX_BD_FLAGS_END; + + num_pkts++; + send_idx = NEXT_TX_BD(send_idx); + + send_bseq += pkt_size; + + REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, send_idx); + REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, send_bseq); + + + udelay(100); + + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW_WO_INT); + REG_RD(bp, BNX2_HC_COMMAND); + + udelay(5); + + pci_unmap_single(bp->pdev, map, pkt_size, PCI_DMA_TODEVICE); + dev_kfree_skb_irq(skb); + + if (bp->status_blk->status_tx_quick_consumer_index0 != send_idx) { + goto loopback_test_done; + } + + rx_idx = bp->status_blk->status_rx_quick_consumer_index0; + if (rx_idx != rx_start_idx + num_pkts) { + goto loopback_test_done; + } + + rx_buf = &bp->rx_buf_ring[rx_start_idx]; + rx_skb = rx_buf->skb; + + rx_hdr = (struct l2_fhdr *) rx_skb->data; + skb_reserve(rx_skb, bp->rx_offset); + + pci_dma_sync_single_for_cpu(bp->pdev, + pci_unmap_addr(rx_buf, mapping), + bp->rx_buf_size, PCI_DMA_FROMDEVICE); + + if (rx_hdr->l2_fhdr_errors & + (L2_FHDR_ERRORS_BAD_CRC | + L2_FHDR_ERRORS_PHY_DECODE | + L2_FHDR_ERRORS_ALIGNMENT | + L2_FHDR_ERRORS_TOO_SHORT | + L2_FHDR_ERRORS_GIANT_FRAME)) { + + goto loopback_test_done; + } + + if ((rx_hdr->l2_fhdr_pkt_len - 4) != pkt_size) { + goto loopback_test_done; + } + + for (i = 14; i < pkt_size; i++) { + if (*(rx_skb->data + i) != (unsigned char) (i & 0xff)) { + goto loopback_test_done; + } + } + + ret = 0; + +loopback_test_done: + bp->loopback = 0; + return ret; +} + +#define NVRAM_SIZE 0x200 +#define CRC32_RESIDUAL 0xdebb20e3 + +static int +bnx2_test_nvram(struct bnx2 *bp) +{ + u32 buf[NVRAM_SIZE / 4]; + u8 *data = (u8 *) buf; + int rc = 0; + u32 magic, csum; + + if ((rc = bnx2_nvram_read(bp, 0, data, 4)) != 0) + goto test_nvram_done; + + magic = be32_to_cpu(buf[0]); + if (magic != 0x669955aa) { + rc = -ENODEV; + goto test_nvram_done; + } + + if ((rc = bnx2_nvram_read(bp, 0x100, data, NVRAM_SIZE)) != 0) + goto test_nvram_done; + + csum = ether_crc_le(0x100, data); + if (csum != CRC32_RESIDUAL) { + rc = -ENODEV; + goto test_nvram_done; + } + + csum = ether_crc_le(0x100, data + 0x100); + if (csum != CRC32_RESIDUAL) { + rc = -ENODEV; + } + +test_nvram_done: + return rc; +} + +static int +bnx2_test_link(struct bnx2 *bp) +{ + u32 bmsr; + + spin_lock_irq(&bp->phy_lock); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + bnx2_read_phy(bp, MII_BMSR, &bmsr); + spin_unlock_irq(&bp->phy_lock); + + if (bmsr & BMSR_LSTATUS) { + return 0; + } + return -ENODEV; +} + +static int +bnx2_test_intr(struct bnx2 *bp) +{ + int i; + u32 val; + u16 status_idx; + + if (!netif_running(bp->dev)) + return -ENODEV; + + status_idx = REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff; + + /* This register is not touched during run-time. */ + val = REG_RD(bp, BNX2_HC_COMMAND); + REG_WR(bp, BNX2_HC_COMMAND, val | BNX2_HC_COMMAND_COAL_NOW); + REG_RD(bp, BNX2_HC_COMMAND); + + for (i = 0; i < 10; i++) { + if ((REG_RD(bp, BNX2_PCICFG_INT_ACK_CMD) & 0xffff) != + status_idx) { + + break; + } + + msleep_interruptible(10); + } + if (i < 10) + return 0; + + return -ENODEV; +} + +static void +bnx2_timer(unsigned long data) +{ + struct bnx2 *bp = (struct bnx2 *) data; + u32 msg; + + if (atomic_read(&bp->intr_sem) != 0) + goto bnx2_restart_timer; + + msg = (u32) ++bp->fw_drv_pulse_wr_seq; + REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg); + + if ((bp->phy_flags & PHY_SERDES_FLAG) && + (CHIP_NUM(bp) == CHIP_NUM_5706)) { + unsigned long flags; + + spin_lock_irqsave(&bp->phy_lock, flags); + if (bp->serdes_an_pending) { + bp->serdes_an_pending--; + } + else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) { + u32 bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + + if (bmcr & BMCR_ANENABLE) { + u32 phy1, phy2; + + bnx2_write_phy(bp, 0x1c, 0x7c00); + bnx2_read_phy(bp, 0x1c, &phy1); + + bnx2_write_phy(bp, 0x17, 0x0f01); + bnx2_read_phy(bp, 0x15, &phy2); + bnx2_write_phy(bp, 0x17, 0x0f01); + bnx2_read_phy(bp, 0x15, &phy2); + + if ((phy1 & 0x10) && /* SIGNAL DETECT */ + !(phy2 & 0x20)) { /* no CONFIG */ + + bmcr &= ~BMCR_ANENABLE; + bmcr |= BMCR_SPEED1000 | + BMCR_FULLDPLX; + bnx2_write_phy(bp, MII_BMCR, bmcr); + bp->phy_flags |= + PHY_PARALLEL_DETECT_FLAG; + } + } + } + else if ((bp->link_up) && (bp->autoneg & AUTONEG_SPEED) && + (bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)) { + u32 phy2; + + bnx2_write_phy(bp, 0x17, 0x0f01); + bnx2_read_phy(bp, 0x15, &phy2); + if (phy2 & 0x20) { + u32 bmcr; + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + bmcr |= BMCR_ANENABLE; + bnx2_write_phy(bp, MII_BMCR, bmcr); + + bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG; + + } + } + + spin_unlock_irqrestore(&bp->phy_lock, flags); + } + +bnx2_restart_timer: + bp->timer.expires = RUN_AT(bp->timer_interval); + + add_timer(&bp->timer); +} + +/* Called with rtnl_lock */ +static int +bnx2_open(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + int rc; + + bnx2_set_power_state(bp, 0); + bnx2_disable_int(bp); + + rc = bnx2_alloc_mem(bp); + if (rc) + return rc; + + if ((CHIP_ID(bp) != CHIP_ID_5706_A0) && + (CHIP_ID(bp) != CHIP_ID_5706_A1) && + !disable_msi) { + + if (pci_enable_msi(bp->pdev) == 0) { + bp->flags |= USING_MSI_FLAG; + rc = request_irq(bp->pdev->irq, bnx2_msi, 0, dev->name, + dev); + } + else { + rc = request_irq(bp->pdev->irq, bnx2_interrupt, + SA_SHIRQ, dev->name, dev); + } + } + else { + rc = request_irq(bp->pdev->irq, bnx2_interrupt, SA_SHIRQ, + dev->name, dev); + } + if (rc) { + bnx2_free_mem(bp); + return rc; + } + + rc = bnx2_init_nic(bp); + + if (rc) { + free_irq(bp->pdev->irq, dev); + if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } + bnx2_free_skbs(bp); + bnx2_free_mem(bp); + return rc; + } + + init_timer(&bp->timer); + + bp->timer.expires = RUN_AT(bp->timer_interval); + bp->timer.data = (unsigned long) bp; + bp->timer.function = bnx2_timer; + add_timer(&bp->timer); + + atomic_set(&bp->intr_sem, 0); + + bnx2_enable_int(bp); + + if (bp->flags & USING_MSI_FLAG) { + /* Test MSI to make sure it is working + * If MSI test fails, go back to INTx mode + */ + if (bnx2_test_intr(bp) != 0) { + printk(KERN_WARNING PFX "%s: No interrupt was generated" + " using MSI, switching to INTx mode. Please" + " report this failure to the PCI maintainer" + " and include system chipset information.\n", + bp->dev->name); + + bnx2_disable_int(bp); + free_irq(bp->pdev->irq, dev); + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + + rc = bnx2_init_nic(bp); + + if (!rc) { + rc = request_irq(bp->pdev->irq, bnx2_interrupt, + SA_SHIRQ, dev->name, dev); + } + if (rc) { + bnx2_free_skbs(bp); + bnx2_free_mem(bp); + del_timer_sync(&bp->timer); + return rc; + } + bnx2_enable_int(bp); + } + } + if (bp->flags & USING_MSI_FLAG) { + printk(KERN_INFO PFX "%s: using MSI\n", dev->name); + } + + netif_start_queue(dev); + + return 0; +} + +static void +bnx2_reset_task(void *data) +{ + struct bnx2 *bp = data; + + bnx2_netif_stop(bp); + + bnx2_init_nic(bp); + + atomic_set(&bp->intr_sem, 1); + bnx2_netif_start(bp); +} + +static void +bnx2_tx_timeout(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + + /* This allows the netif to be shutdown gracefully before resetting */ + schedule_work(&bp->reset_task); +} + +#ifdef BCM_VLAN +/* Called with rtnl_lock */ +static void +bnx2_vlan_rx_register(struct net_device *dev, struct vlan_group *vlgrp) +{ + struct bnx2 *bp = dev->priv; + + bnx2_netif_stop(bp); + + bp->vlgrp = vlgrp; + bnx2_set_rx_mode(dev); + + bnx2_netif_start(bp); +} + +/* Called with rtnl_lock */ +static void +bnx2_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) +{ + struct bnx2 *bp = dev->priv; + + bnx2_netif_stop(bp); + + if (bp->vlgrp) + bp->vlgrp->vlan_devices[vid] = NULL; + bnx2_set_rx_mode(dev); + + bnx2_netif_start(bp); +} +#endif + +/* Called with dev->xmit_lock. + * hard_start_xmit is pseudo-lockless - a lock is only required when + * the tx queue is full. This way, we get the benefit of lockless + * operations most of the time without the complexities to handle + * netif_stop_queue/wake_queue race conditions. + */ +static int +bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + dma_addr_t mapping; + struct tx_bd *txbd; + struct sw_bd *tx_buf; + u32 len, vlan_tag_flags, last_frag, mss; + u16 prod, ring_prod; + int i; + + if (unlikely(atomic_read(&bp->tx_avail_bd) < + (skb_shinfo(skb)->nr_frags + 1))) { + + netif_stop_queue(dev); + printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n", + dev->name); + + return NETDEV_TX_BUSY; + } + len = skb_headlen(skb); + prod = bp->tx_prod; + ring_prod = TX_RING_IDX(prod); + + vlan_tag_flags = 0; + if (skb->ip_summed == CHECKSUM_HW) { + vlan_tag_flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; + } + + if (bp->vlgrp != 0 && vlan_tx_tag_present(skb)) { + vlan_tag_flags |= + (TX_BD_FLAGS_VLAN_TAG | (vlan_tx_tag_get(skb) << 16)); + } +#ifdef BCM_TSO + if ((mss = skb_shinfo(skb)->tso_size) && + (skb->len > (bp->dev->mtu + ETH_HLEN))) { + u32 tcp_opt_len, ip_tcp_len; + + if (skb_header_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } + + tcp_opt_len = ((skb->h.th->doff - 5) * 4); + vlan_tag_flags |= TX_BD_FLAGS_SW_LSO; + + tcp_opt_len = 0; + if (skb->h.th->doff > 5) { + tcp_opt_len = (skb->h.th->doff - 5) << 2; + } + ip_tcp_len = (skb->nh.iph->ihl << 2) + sizeof(struct tcphdr); + + skb->nh.iph->check = 0; + skb->nh.iph->tot_len = ntohs(mss + ip_tcp_len + tcp_opt_len); + skb->h.th->check = + ~csum_tcpudp_magic(skb->nh.iph->saddr, + skb->nh.iph->daddr, + 0, IPPROTO_TCP, 0); + + if (tcp_opt_len || (skb->nh.iph->ihl > 5)) { + vlan_tag_flags |= ((skb->nh.iph->ihl - 5) + + (tcp_opt_len >> 2)) << 8; + } + } + else +#endif + { + mss = 0; + } + + mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); + + tx_buf = &bp->tx_buf_ring[ring_prod]; + tx_buf->skb = skb; + pci_unmap_addr_set(tx_buf, mapping, mapping); + + txbd = &bp->tx_desc_ring[ring_prod]; + + txbd->tx_bd_haddr_hi = (u64) mapping >> 32; + txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff; + txbd->tx_bd_mss_nbytes = len | (mss << 16); + txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START; + + last_frag = skb_shinfo(skb)->nr_frags; + + for (i = 0; i < last_frag; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + + prod = NEXT_TX_BD(prod); + ring_prod = TX_RING_IDX(prod); + txbd = &bp->tx_desc_ring[ring_prod]; + + len = frag->size; + mapping = pci_map_page(bp->pdev, frag->page, frag->page_offset, + len, PCI_DMA_TODEVICE); + pci_unmap_addr_set(&bp->tx_buf_ring[ring_prod], + mapping, mapping); + + txbd->tx_bd_haddr_hi = (u64) mapping >> 32; + txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff; + txbd->tx_bd_mss_nbytes = len | (mss << 16); + txbd->tx_bd_vlan_tag_flags = vlan_tag_flags; + + } + txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END; + + prod = NEXT_TX_BD(prod); + bp->tx_prod_bseq += skb->len; + + atomic_sub(last_frag + 1, &bp->tx_avail_bd); + + REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod); + REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq); + + mmiowb(); + + bp->tx_prod = prod; + dev->trans_start = jiffies; + + if (unlikely(atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS)) { + unsigned long flags; + + spin_lock_irqsave(&bp->tx_lock, flags); + if (atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS) { + netif_stop_queue(dev); + + if (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS) + netif_wake_queue(dev); + } + spin_unlock_irqrestore(&bp->tx_lock, flags); + } + + return NETDEV_TX_OK; +} + +/* Called with rtnl_lock */ +static int +bnx2_close(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + u32 reset_code; + + flush_scheduled_work(); + bnx2_netif_stop(bp); + del_timer_sync(&bp->timer); + if (bp->wol) + reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL; + else + reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; + bnx2_reset_chip(bp, reset_code); + free_irq(bp->pdev->irq, dev); + if (bp->flags & USING_MSI_FLAG) { + pci_disable_msi(bp->pdev); + bp->flags &= ~USING_MSI_FLAG; + } + bnx2_free_skbs(bp); + bnx2_free_mem(bp); + bp->link_up = 0; + netif_carrier_off(bp->dev); + bnx2_set_power_state(bp, 3); + return 0; +} + +#define GET_NET_STATS64(ctr) \ + (unsigned long) ((unsigned long) (ctr##_hi) << 32) + \ + (unsigned long) (ctr##_lo) + +#define GET_NET_STATS32(ctr) \ + (ctr##_lo) + +#if (BITS_PER_LONG == 64) +#define GET_NET_STATS GET_NET_STATS64 +#else +#define GET_NET_STATS GET_NET_STATS32 +#endif + +static struct net_device_stats * +bnx2_get_stats(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + struct statistics_block *stats_blk = bp->stats_blk; + struct net_device_stats *net_stats = &bp->net_stats; + + if (bp->stats_blk == NULL) { + return net_stats; + } + net_stats->rx_packets = + GET_NET_STATS(stats_blk->stat_IfHCInUcastPkts) + + GET_NET_STATS(stats_blk->stat_IfHCInMulticastPkts) + + GET_NET_STATS(stats_blk->stat_IfHCInBroadcastPkts); + + net_stats->tx_packets = + GET_NET_STATS(stats_blk->stat_IfHCOutUcastPkts) + + GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts) + + GET_NET_STATS(stats_blk->stat_IfHCOutBroadcastPkts); + + net_stats->rx_bytes = + GET_NET_STATS(stats_blk->stat_IfHCInOctets); + + net_stats->tx_bytes = + GET_NET_STATS(stats_blk->stat_IfHCOutOctets); + + net_stats->multicast = + GET_NET_STATS(stats_blk->stat_IfHCOutMulticastPkts); + + net_stats->collisions = + (unsigned long) stats_blk->stat_EtherStatsCollisions; + + net_stats->rx_length_errors = + (unsigned long) (stats_blk->stat_EtherStatsUndersizePkts + + stats_blk->stat_EtherStatsOverrsizePkts); + + net_stats->rx_over_errors = + (unsigned long) stats_blk->stat_IfInMBUFDiscards; + + net_stats->rx_frame_errors = + (unsigned long) stats_blk->stat_Dot3StatsAlignmentErrors; + + net_stats->rx_crc_errors = + (unsigned long) stats_blk->stat_Dot3StatsFCSErrors; + + net_stats->rx_errors = net_stats->rx_length_errors + + net_stats->rx_over_errors + net_stats->rx_frame_errors + + net_stats->rx_crc_errors; + + net_stats->tx_aborted_errors = + (unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions + + stats_blk->stat_Dot3StatsLateCollisions); + + if (CHIP_NUM(bp) == CHIP_NUM_5706) + net_stats->tx_carrier_errors = 0; + else { + net_stats->tx_carrier_errors = + (unsigned long) + stats_blk->stat_Dot3StatsCarrierSenseErrors; + } + + net_stats->tx_errors = + (unsigned long) + stats_blk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors + + + net_stats->tx_aborted_errors + + net_stats->tx_carrier_errors; + + return net_stats; +} + +/* All ethtool functions called with rtnl_lock */ + +static int +bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct bnx2 *bp = dev->priv; + + cmd->supported = SUPPORTED_Autoneg; + if (bp->phy_flags & PHY_SERDES_FLAG) { + cmd->supported |= SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE; + + cmd->port = PORT_FIBRE; + } + else { + cmd->supported |= SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Full | + SUPPORTED_TP; + + cmd->port = PORT_TP; + } + + cmd->advertising = bp->advertising; + + if (bp->autoneg & AUTONEG_SPEED) { + cmd->autoneg = AUTONEG_ENABLE; + } + else { + cmd->autoneg = AUTONEG_DISABLE; + } + + if (netif_carrier_ok(dev)) { + cmd->speed = bp->line_speed; + cmd->duplex = bp->duplex; + } + else { + cmd->speed = -1; + cmd->duplex = -1; + } + + cmd->transceiver = XCVR_INTERNAL; + cmd->phy_address = bp->phy_addr; + + return 0; +} + +static int +bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + struct bnx2 *bp = dev->priv; + u8 autoneg = bp->autoneg; + u8 req_duplex = bp->req_duplex; + u16 req_line_speed = bp->req_line_speed; + u32 advertising = bp->advertising; + + if (cmd->autoneg == AUTONEG_ENABLE) { + autoneg |= AUTONEG_SPEED; + + cmd->advertising &= ETHTOOL_ALL_COPPER_SPEED; + + /* allow advertising 1 speed */ + if ((cmd->advertising == ADVERTISED_10baseT_Half) || + (cmd->advertising == ADVERTISED_10baseT_Full) || + (cmd->advertising == ADVERTISED_100baseT_Half) || + (cmd->advertising == ADVERTISED_100baseT_Full)) { + + if (bp->phy_flags & PHY_SERDES_FLAG) + return -EINVAL; + + advertising = cmd->advertising; + + } + else if (cmd->advertising == ADVERTISED_1000baseT_Full) { + advertising = cmd->advertising; + } + else if (cmd->advertising == ADVERTISED_1000baseT_Half) { + return -EINVAL; + } + else { + if (bp->phy_flags & PHY_SERDES_FLAG) { + advertising = ETHTOOL_ALL_FIBRE_SPEED; + } + else { + advertising = ETHTOOL_ALL_COPPER_SPEED; + } + } + advertising |= ADVERTISED_Autoneg; + } + else { + if (bp->phy_flags & PHY_SERDES_FLAG) { + if ((cmd->speed != SPEED_1000) || + (cmd->duplex != DUPLEX_FULL)) { + return -EINVAL; + } + } + else if (cmd->speed == SPEED_1000) { + return -EINVAL; + } + autoneg &= ~AUTONEG_SPEED; + req_line_speed = cmd->speed; + req_duplex = cmd->duplex; + advertising = 0; + } + + bp->autoneg = autoneg; + bp->advertising = advertising; + bp->req_line_speed = req_line_speed; + bp->req_duplex = req_duplex; + + spin_lock_irq(&bp->phy_lock); + + bnx2_setup_phy(bp); + + spin_unlock_irq(&bp->phy_lock); + + return 0; +} + +static void +bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct bnx2 *bp = dev->priv; + + strcpy(info->driver, DRV_MODULE_NAME); + strcpy(info->version, DRV_MODULE_VERSION); + strcpy(info->bus_info, pci_name(bp->pdev)); + info->fw_version[0] = ((bp->fw_ver & 0xff000000) >> 24) + '0'; + info->fw_version[2] = ((bp->fw_ver & 0xff0000) >> 16) + '0'; + info->fw_version[4] = ((bp->fw_ver & 0xff00) >> 8) + '0'; + info->fw_version[6] = (bp->fw_ver & 0xff) + '0'; + info->fw_version[1] = info->fw_version[3] = info->fw_version[5] = '.'; + info->fw_version[7] = 0; +} + +static void +bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct bnx2 *bp = dev->priv; + + if (bp->flags & NO_WOL_FLAG) { + wol->supported = 0; + wol->wolopts = 0; + } + else { + wol->supported = WAKE_MAGIC; + if (bp->wol) + wol->wolopts = WAKE_MAGIC; + else + wol->wolopts = 0; + } + memset(&wol->sopass, 0, sizeof(wol->sopass)); +} + +static int +bnx2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct bnx2 *bp = dev->priv; + + if (wol->wolopts & ~WAKE_MAGIC) + return -EINVAL; + + if (wol->wolopts & WAKE_MAGIC) { + if (bp->flags & NO_WOL_FLAG) + return -EINVAL; + + bp->wol = 1; + } + else { + bp->wol = 0; + } + return 0; +} + +static int +bnx2_nway_reset(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + u32 bmcr; + + if (!(bp->autoneg & AUTONEG_SPEED)) { + return -EINVAL; + } + + spin_lock_irq(&bp->phy_lock); + + /* Force a link down visible on the other side */ + if (bp->phy_flags & PHY_SERDES_FLAG) { + bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK); + spin_unlock_irq(&bp->phy_lock); + + msleep(20); + + spin_lock_irq(&bp->phy_lock); + if (CHIP_NUM(bp) == CHIP_NUM_5706) { + bp->serdes_an_pending = SERDES_AN_TIMEOUT / + bp->timer_interval; + } + } + + bnx2_read_phy(bp, MII_BMCR, &bmcr); + bmcr &= ~BMCR_LOOPBACK; + bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE); + + spin_unlock_irq(&bp->phy_lock); + + return 0; +} + +static int +bnx2_get_eeprom_len(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + + if (bp->flash_info == 0) + return 0; + + return (int) bp->flash_info->total_size; +} + +static int +bnx2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + u8 *eebuf) +{ + struct bnx2 *bp = dev->priv; + int rc; + + if (eeprom->offset > bp->flash_info->total_size) + return -EINVAL; + + if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size) + eeprom->len = bp->flash_info->total_size - eeprom->offset; + + rc = bnx2_nvram_read(bp, eeprom->offset, eebuf, eeprom->len); + + return rc; +} + +static int +bnx2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, + u8 *eebuf) +{ + struct bnx2 *bp = dev->priv; + int rc; + + if (eeprom->offset > bp->flash_info->total_size) + return -EINVAL; + + if ((eeprom->offset + eeprom->len) > bp->flash_info->total_size) + eeprom->len = bp->flash_info->total_size - eeprom->offset; + + rc = bnx2_nvram_write(bp, eeprom->offset, eebuf, eeprom->len); + + return rc; +} + +static int +bnx2_get_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) +{ + struct bnx2 *bp = dev->priv; + + memset(coal, 0, sizeof(struct ethtool_coalesce)); + + coal->rx_coalesce_usecs = bp->rx_ticks; + coal->rx_max_coalesced_frames = bp->rx_quick_cons_trip; + coal->rx_coalesce_usecs_irq = bp->rx_ticks_int; + coal->rx_max_coalesced_frames_irq = bp->rx_quick_cons_trip_int; + + coal->tx_coalesce_usecs = bp->tx_ticks; + coal->tx_max_coalesced_frames = bp->tx_quick_cons_trip; + coal->tx_coalesce_usecs_irq = bp->tx_ticks_int; + coal->tx_max_coalesced_frames_irq = bp->tx_quick_cons_trip_int; + + coal->stats_block_coalesce_usecs = bp->stats_ticks; + + return 0; +} + +static int +bnx2_set_coalesce(struct net_device *dev, struct ethtool_coalesce *coal) +{ + struct bnx2 *bp = dev->priv; + + bp->rx_ticks = (u16) coal->rx_coalesce_usecs; + if (bp->rx_ticks > 0x3ff) bp->rx_ticks = 0x3ff; + + bp->rx_quick_cons_trip = (u16) coal->rx_max_coalesced_frames; + if (bp->rx_quick_cons_trip > 0xff) bp->rx_quick_cons_trip = 0xff; + + bp->rx_ticks_int = (u16) coal->rx_coalesce_usecs_irq; + if (bp->rx_ticks_int > 0x3ff) bp->rx_ticks_int = 0x3ff; + + bp->rx_quick_cons_trip_int = (u16) coal->rx_max_coalesced_frames_irq; + if (bp->rx_quick_cons_trip_int > 0xff) + bp->rx_quick_cons_trip_int = 0xff; + + bp->tx_ticks = (u16) coal->tx_coalesce_usecs; + if (bp->tx_ticks > 0x3ff) bp->tx_ticks = 0x3ff; + + bp->tx_quick_cons_trip = (u16) coal->tx_max_coalesced_frames; + if (bp->tx_quick_cons_trip > 0xff) bp->tx_quick_cons_trip = 0xff; + + bp->tx_ticks_int = (u16) coal->tx_coalesce_usecs_irq; + if (bp->tx_ticks_int > 0x3ff) bp->tx_ticks_int = 0x3ff; + + bp->tx_quick_cons_trip_int = (u16) coal->tx_max_coalesced_frames_irq; + if (bp->tx_quick_cons_trip_int > 0xff) bp->tx_quick_cons_trip_int = + 0xff; + + bp->stats_ticks = coal->stats_block_coalesce_usecs; + if (bp->stats_ticks > 0xffff00) bp->stats_ticks = 0xffff00; + bp->stats_ticks &= 0xffff00; + + if (netif_running(bp->dev)) { + bnx2_netif_stop(bp); + bnx2_init_nic(bp); + bnx2_netif_start(bp); + } + + return 0; +} + +static void +bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct bnx2 *bp = dev->priv; + + ering->rx_max_pending = MAX_RX_DESC_CNT; + ering->rx_mini_max_pending = 0; + ering->rx_jumbo_max_pending = 0; + + ering->rx_pending = bp->rx_ring_size; + ering->rx_mini_pending = 0; + ering->rx_jumbo_pending = 0; + + ering->tx_max_pending = MAX_TX_DESC_CNT; + ering->tx_pending = bp->tx_ring_size; +} + +static int +bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) +{ + struct bnx2 *bp = dev->priv; + + if ((ering->rx_pending > MAX_RX_DESC_CNT) || + (ering->tx_pending > MAX_TX_DESC_CNT) || + (ering->tx_pending <= MAX_SKB_FRAGS)) { + + return -EINVAL; + } + bp->rx_ring_size = ering->rx_pending; + bp->tx_ring_size = ering->tx_pending; + + if (netif_running(bp->dev)) { + bnx2_netif_stop(bp); + bnx2_init_nic(bp); + bnx2_netif_start(bp); + } + + return 0; +} + +static void +bnx2_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) +{ + struct bnx2 *bp = dev->priv; + + epause->autoneg = ((bp->autoneg & AUTONEG_FLOW_CTRL) != 0); + epause->rx_pause = ((bp->flow_ctrl & FLOW_CTRL_RX) != 0); + epause->tx_pause = ((bp->flow_ctrl & FLOW_CTRL_TX) != 0); +} + +static int +bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) +{ + struct bnx2 *bp = dev->priv; + + bp->req_flow_ctrl = 0; + if (epause->rx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_RX; + if (epause->tx_pause) + bp->req_flow_ctrl |= FLOW_CTRL_TX; + + if (epause->autoneg) { + bp->autoneg |= AUTONEG_FLOW_CTRL; + } + else { + bp->autoneg &= ~AUTONEG_FLOW_CTRL; + } + + spin_lock_irq(&bp->phy_lock); + + bnx2_setup_phy(bp); + + spin_unlock_irq(&bp->phy_lock); + + return 0; +} + +static u32 +bnx2_get_rx_csum(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + + return bp->rx_csum; +} + +static int +bnx2_set_rx_csum(struct net_device *dev, u32 data) +{ + struct bnx2 *bp = dev->priv; + + bp->rx_csum = data; + return 0; +} + +#define BNX2_NUM_STATS 45 + +struct { + char string[ETH_GSTRING_LEN]; +} bnx2_stats_str_arr[BNX2_NUM_STATS] = { + { "rx_bytes" }, + { "rx_error_bytes" }, + { "tx_bytes" }, + { "tx_error_bytes" }, + { "rx_ucast_packets" }, + { "rx_mcast_packets" }, + { "rx_bcast_packets" }, + { "tx_ucast_packets" }, + { "tx_mcast_packets" }, + { "tx_bcast_packets" }, + { "tx_mac_errors" }, + { "tx_carrier_errors" }, + { "rx_crc_errors" }, + { "rx_align_errors" }, + { "tx_single_collisions" }, + { "tx_multi_collisions" }, + { "tx_deferred" }, + { "tx_excess_collisions" }, + { "tx_late_collisions" }, + { "tx_total_collisions" }, + { "rx_fragments" }, + { "rx_jabbers" }, + { "rx_undersize_packets" }, + { "rx_oversize_packets" }, + { "rx_64_byte_packets" }, + { "rx_65_to_127_byte_packets" }, + { "rx_128_to_255_byte_packets" }, + { "rx_256_to_511_byte_packets" }, + { "rx_512_to_1023_byte_packets" }, + { "rx_1024_to_1522_byte_packets" }, + { "rx_1523_to_9022_byte_packets" }, + { "tx_64_byte_packets" }, + { "tx_65_to_127_byte_packets" }, + { "tx_128_to_255_byte_packets" }, + { "tx_256_to_511_byte_packets" }, + { "tx_512_to_1023_byte_packets" }, + { "tx_1024_to_1522_byte_packets" }, + { "tx_1523_to_9022_byte_packets" }, + { "rx_xon_frames" }, + { "rx_xoff_frames" }, + { "tx_xon_frames" }, + { "tx_xoff_frames" }, + { "rx_mac_ctrl_frames" }, + { "rx_filtered_packets" }, + { "rx_discards" }, +}; + +#define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4) + +unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = { + STATS_OFFSET32(stat_IfHCInOctets_hi), + STATS_OFFSET32(stat_IfHCInBadOctets_hi), + STATS_OFFSET32(stat_IfHCOutOctets_hi), + STATS_OFFSET32(stat_IfHCOutBadOctets_hi), + STATS_OFFSET32(stat_IfHCInUcastPkts_hi), + STATS_OFFSET32(stat_IfHCInMulticastPkts_hi), + STATS_OFFSET32(stat_IfHCInBroadcastPkts_hi), + STATS_OFFSET32(stat_IfHCOutUcastPkts_hi), + STATS_OFFSET32(stat_IfHCOutMulticastPkts_hi), + STATS_OFFSET32(stat_IfHCOutBroadcastPkts_hi), + STATS_OFFSET32(stat_emac_tx_stat_dot3statsinternalmactransmiterrors), + STATS_OFFSET32(stat_Dot3StatsCarrierSenseErrors), + STATS_OFFSET32(stat_Dot3StatsFCSErrors), + STATS_OFFSET32(stat_Dot3StatsAlignmentErrors), + STATS_OFFSET32(stat_Dot3StatsSingleCollisionFrames), + STATS_OFFSET32(stat_Dot3StatsMultipleCollisionFrames), + STATS_OFFSET32(stat_Dot3StatsDeferredTransmissions), + STATS_OFFSET32(stat_Dot3StatsExcessiveCollisions), + STATS_OFFSET32(stat_Dot3StatsLateCollisions), + STATS_OFFSET32(stat_EtherStatsCollisions), + STATS_OFFSET32(stat_EtherStatsFragments), + STATS_OFFSET32(stat_EtherStatsJabbers), + STATS_OFFSET32(stat_EtherStatsUndersizePkts), + STATS_OFFSET32(stat_EtherStatsOverrsizePkts), + STATS_OFFSET32(stat_EtherStatsPktsRx64Octets), + STATS_OFFSET32(stat_EtherStatsPktsRx65Octetsto127Octets), + STATS_OFFSET32(stat_EtherStatsPktsRx128Octetsto255Octets), + STATS_OFFSET32(stat_EtherStatsPktsRx256Octetsto511Octets), + STATS_OFFSET32(stat_EtherStatsPktsRx512Octetsto1023Octets), + STATS_OFFSET32(stat_EtherStatsPktsRx1024Octetsto1522Octets), + STATS_OFFSET32(stat_EtherStatsPktsRx1523Octetsto9022Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx64Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx65Octetsto127Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx128Octetsto255Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx256Octetsto511Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx512Octetsto1023Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx1024Octetsto1522Octets), + STATS_OFFSET32(stat_EtherStatsPktsTx1523Octetsto9022Octets), + STATS_OFFSET32(stat_XonPauseFramesReceived), + STATS_OFFSET32(stat_XoffPauseFramesReceived), + STATS_OFFSET32(stat_OutXonSent), + STATS_OFFSET32(stat_OutXoffSent), + STATS_OFFSET32(stat_MacControlFramesReceived), + STATS_OFFSET32(stat_IfInFramesL2FilterDiscards), + STATS_OFFSET32(stat_IfInMBUFDiscards), +}; + +/* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are + * skipped because of errata. + */ +u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = { + 8,0,8,8,8,8,8,8,8,8, + 4,0,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4, +}; + +#define BNX2_NUM_TESTS 6 + +struct { + char string[ETH_GSTRING_LEN]; +} bnx2_tests_str_arr[BNX2_NUM_TESTS] = { + { "register_test (offline)" }, + { "memory_test (offline)" }, + { "loopback_test (offline)" }, + { "nvram_test (online)" }, + { "interrupt_test (online)" }, + { "link_test (online)" }, +}; + +static int +bnx2_self_test_count(struct net_device *dev) +{ + return BNX2_NUM_TESTS; +} + +static void +bnx2_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *buf) +{ + struct bnx2 *bp = dev->priv; + + memset(buf, 0, sizeof(u64) * BNX2_NUM_TESTS); + if (etest->flags & ETH_TEST_FL_OFFLINE) { + bnx2_netif_stop(bp); + bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_DIAG); + bnx2_free_skbs(bp); + + if (bnx2_test_registers(bp) != 0) { + buf[0] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (bnx2_test_memory(bp) != 0) { + buf[1] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (bnx2_test_loopback(bp) != 0) { + buf[2] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + + if (!netif_running(bp->dev)) { + bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET); + } + else { + bnx2_init_nic(bp); + bnx2_netif_start(bp); + } + + /* wait for link up */ + msleep_interruptible(3000); + if ((!bp->link_up) && !(bp->phy_flags & PHY_SERDES_FLAG)) + msleep_interruptible(4000); + } + + if (bnx2_test_nvram(bp) != 0) { + buf[3] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + if (bnx2_test_intr(bp) != 0) { + buf[4] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + } + + if (bnx2_test_link(bp) != 0) { + buf[5] = 1; + etest->flags |= ETH_TEST_FL_FAILED; + + } +} + +static void +bnx2_get_strings(struct net_device *dev, u32 stringset, u8 *buf) +{ + switch (stringset) { + case ETH_SS_STATS: + memcpy(buf, bnx2_stats_str_arr, + sizeof(bnx2_stats_str_arr)); + break; + case ETH_SS_TEST: + memcpy(buf, bnx2_tests_str_arr, + sizeof(bnx2_tests_str_arr)); + break; + } +} + +static int +bnx2_get_stats_count(struct net_device *dev) +{ + return BNX2_NUM_STATS; +} + +static void +bnx2_get_ethtool_stats(struct net_device *dev, + struct ethtool_stats *stats, u64 *buf) +{ + struct bnx2 *bp = dev->priv; + int i; + u32 *hw_stats = (u32 *) bp->stats_blk; + u8 *stats_len_arr = 0; + + if (hw_stats == NULL) { + memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS); + return; + } + + if (CHIP_NUM(bp) == CHIP_NUM_5706) + stats_len_arr = bnx2_5706_stats_len_arr; + + for (i = 0; i < BNX2_NUM_STATS; i++) { + if (stats_len_arr[i] == 0) { + /* skip this counter */ + buf[i] = 0; + continue; + } + if (stats_len_arr[i] == 4) { + /* 4-byte counter */ + buf[i] = (u64) + *(hw_stats + bnx2_stats_offset_arr[i]); + continue; + } + /* 8-byte counter */ + buf[i] = (((u64) *(hw_stats + + bnx2_stats_offset_arr[i])) << 32) + + *(hw_stats + bnx2_stats_offset_arr[i] + 1); + } +} + +static int +bnx2_phys_id(struct net_device *dev, u32 data) +{ + struct bnx2 *bp = dev->priv; + int i; + u32 save; + + if (data == 0) + data = 2; + + save = REG_RD(bp, BNX2_MISC_CFG); + REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC); + + for (i = 0; i < (data * 2); i++) { + if ((i % 2) == 0) { + REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE); + } + else { + REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE | + BNX2_EMAC_LED_1000MB_OVERRIDE | + BNX2_EMAC_LED_100MB_OVERRIDE | + BNX2_EMAC_LED_10MB_OVERRIDE | + BNX2_EMAC_LED_TRAFFIC_OVERRIDE | + BNX2_EMAC_LED_TRAFFIC); + } + msleep_interruptible(500); + if (signal_pending(current)) + break; + } + REG_WR(bp, BNX2_EMAC_LED, 0); + REG_WR(bp, BNX2_MISC_CFG, save); + return 0; +} + +static struct ethtool_ops bnx2_ethtool_ops = { + .get_settings = bnx2_get_settings, + .set_settings = bnx2_set_settings, + .get_drvinfo = bnx2_get_drvinfo, + .get_wol = bnx2_get_wol, + .set_wol = bnx2_set_wol, + .nway_reset = bnx2_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = bnx2_get_eeprom_len, + .get_eeprom = bnx2_get_eeprom, + .set_eeprom = bnx2_set_eeprom, + .get_coalesce = bnx2_get_coalesce, + .set_coalesce = bnx2_set_coalesce, + .get_ringparam = bnx2_get_ringparam, + .set_ringparam = bnx2_set_ringparam, + .get_pauseparam = bnx2_get_pauseparam, + .set_pauseparam = bnx2_set_pauseparam, + .get_rx_csum = bnx2_get_rx_csum, + .set_rx_csum = bnx2_set_rx_csum, + .get_tx_csum = ethtool_op_get_tx_csum, + .set_tx_csum = ethtool_op_set_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef BCM_TSO + .get_tso = ethtool_op_get_tso, + .set_tso = ethtool_op_set_tso, +#endif + .self_test_count = bnx2_self_test_count, + .self_test = bnx2_self_test, + .get_strings = bnx2_get_strings, + .phys_id = bnx2_phys_id, + .get_stats_count = bnx2_get_stats_count, + .get_ethtool_stats = bnx2_get_ethtool_stats, +}; + +/* Called with rtnl_lock */ +static int +bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +{ + struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data; + struct bnx2 *bp = dev->priv; + int err; + + switch(cmd) { + case SIOCGMIIPHY: + data->phy_id = bp->phy_addr; + + /* fallthru */ + case SIOCGMIIREG: { + u32 mii_regval; + + spin_lock_irq(&bp->phy_lock); + err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval); + spin_unlock_irq(&bp->phy_lock); + + data->val_out = mii_regval; + + return err; + } + + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + spin_lock_irq(&bp->phy_lock); + err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in); + spin_unlock_irq(&bp->phy_lock); + + return err; + + default: + /* do nothing */ + break; + } + return -EOPNOTSUPP; +} + +/* Called with rtnl_lock */ +static int +bnx2_change_mac_addr(struct net_device *dev, void *p) +{ + struct sockaddr *addr = p; + struct bnx2 *bp = dev->priv; + + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); + if (netif_running(dev)) + bnx2_set_mac_addr(bp); + + return 0; +} + +/* Called with rtnl_lock */ +static int +bnx2_change_mtu(struct net_device *dev, int new_mtu) +{ + struct bnx2 *bp = dev->priv; + + if (((new_mtu + ETH_HLEN) > MAX_ETHERNET_JUMBO_PACKET_SIZE) || + ((new_mtu + ETH_HLEN) < MIN_ETHERNET_PACKET_SIZE)) + return -EINVAL; + + dev->mtu = new_mtu; + if (netif_running(dev)) { + bnx2_netif_stop(bp); + + bnx2_init_nic(bp); + + bnx2_netif_start(bp); + } + return 0; +} + +#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER) +static void +poll_bnx2(struct net_device *dev) +{ + struct bnx2 *bp = dev->priv; + + disable_irq(bp->pdev->irq); + bnx2_interrupt(bp->pdev->irq, dev, NULL); + enable_irq(bp->pdev->irq); +} +#endif + +static int __devinit +bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) +{ + struct bnx2 *bp; + unsigned long mem_len; + int rc; + u32 reg; + + SET_MODULE_OWNER(dev); + SET_NETDEV_DEV(dev, &pdev->dev); + bp = dev->priv; + + bp->flags = 0; + bp->phy_flags = 0; + + /* enable device (incl. PCI PM wakeup), and bus-mastering */ + rc = pci_enable_device(pdev); + if (rc) { + printk(KERN_ERR PFX "Cannot enable PCI device, aborting."); + goto err_out; + } + + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { + printk(KERN_ERR PFX "Cannot find PCI device base address, " + "aborting.\n"); + rc = -ENODEV; + goto err_out_disable; + } + + rc = pci_request_regions(pdev, DRV_MODULE_NAME); + if (rc) { + printk(KERN_ERR PFX "Cannot obtain PCI resources, aborting.\n"); + goto err_out_disable; + } + + pci_set_master(pdev); + + bp->pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (bp->pm_cap == 0) { + printk(KERN_ERR PFX "Cannot find power management capability, " + "aborting.\n"); + rc = -EIO; + goto err_out_release; + } + + bp->pcix_cap = pci_find_capability(pdev, PCI_CAP_ID_PCIX); + if (bp->pcix_cap == 0) { + printk(KERN_ERR PFX "Cannot find PCIX capability, aborting.\n"); + rc = -EIO; + goto err_out_release; + } + + if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) == 0) { + bp->flags |= USING_DAC_FLAG; + if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK) != 0) { + printk(KERN_ERR PFX "pci_set_consistent_dma_mask " + "failed, aborting.\n"); + rc = -EIO; + goto err_out_release; + } + } + else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0) { + printk(KERN_ERR PFX "System does not support DMA, aborting.\n"); + rc = -EIO; + goto err_out_release; + } + + bp->dev = dev; + bp->pdev = pdev; + + spin_lock_init(&bp->phy_lock); + spin_lock_init(&bp->tx_lock); + INIT_WORK(&bp->reset_task, bnx2_reset_task, bp); + + dev->base_addr = dev->mem_start = pci_resource_start(pdev, 0); + mem_len = MB_GET_CID_ADDR(17); + dev->mem_end = dev->mem_start + mem_len; + dev->irq = pdev->irq; + + bp->regview = ioremap_nocache(dev->base_addr, mem_len); + + if (!bp->regview) { + printk(KERN_ERR PFX "Cannot map register space, aborting.\n"); + rc = -ENOMEM; + goto err_out_release; + } + + /* Configure byte swap and enable write to the reg_window registers. + * Rely on CPU to do target byte swapping on big endian systems + * The chip's target access swapping will not swap all accesses + */ + pci_write_config_dword(bp->pdev, BNX2_PCICFG_MISC_CONFIG, + BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | + BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP); + + bnx2_set_power_state(bp, 0); + + bp->chip_id = REG_RD(bp, BNX2_MISC_ID); + + bp->phy_addr = 1; + + /* Get bus information. */ + reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS); + if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) { + u32 clkreg; + + bp->flags |= PCIX_FLAG; + + clkreg = REG_RD(bp, BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS); + + clkreg &= BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET; + switch (clkreg) { + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: + bp->bus_speed_mhz = 133; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: + bp->bus_speed_mhz = 100; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: + bp->bus_speed_mhz = 66; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: + bp->bus_speed_mhz = 50; + break; + + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: + case BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: + bp->bus_speed_mhz = 33; + break; + } + } + else { + if (reg & BNX2_PCICFG_MISC_STATUS_M66EN) + bp->bus_speed_mhz = 66; + else + bp->bus_speed_mhz = 33; + } + + if (reg & BNX2_PCICFG_MISC_STATUS_32BIT_DET) + bp->flags |= PCI_32BIT_FLAG; + + /* 5706A0 may falsely detect SERR and PERR. */ + if (CHIP_ID(bp) == CHIP_ID_5706_A0) { + reg = REG_RD(bp, PCI_COMMAND); + reg &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); + REG_WR(bp, PCI_COMMAND, reg); + } + else if ((CHIP_ID(bp) == CHIP_ID_5706_A1) && + !(bp->flags & PCIX_FLAG)) { + + printk(KERN_ERR PFX "5706 A1 can only be used in a PCIX bus, " + "aborting.\n"); + goto err_out_unmap; + } + + bnx2_init_nvram(bp); + + /* Get the permanent MAC address. First we need to make sure the + * firmware is actually running. + */ + reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE); + + if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != + BNX2_DEV_INFO_SIGNATURE_MAGIC) { + printk(KERN_ERR PFX "Firmware not running, aborting.\n"); + rc = -ENODEV; + goto err_out_unmap; + } + + bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + + BNX2_DEV_INFO_BC_REV); + + reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER); + bp->mac_addr[0] = (u8) (reg >> 8); + bp->mac_addr[1] = (u8) reg; + + reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER); + bp->mac_addr[2] = (u8) (reg >> 24); + bp->mac_addr[3] = (u8) (reg >> 16); + bp->mac_addr[4] = (u8) (reg >> 8); + bp->mac_addr[5] = (u8) reg; + + bp->tx_ring_size = MAX_TX_DESC_CNT; + bp->rx_ring_size = 100; + + bp->rx_csum = 1; + + bp->rx_offset = sizeof(struct l2_fhdr) + 2; + + bp->tx_quick_cons_trip_int = 20; + bp->tx_quick_cons_trip = 20; + bp->tx_ticks_int = 80; + bp->tx_ticks = 80; + + bp->rx_quick_cons_trip_int = 6; + bp->rx_quick_cons_trip = 6; + bp->rx_ticks_int = 18; + bp->rx_ticks = 18; + + bp->stats_ticks = 1000000 & 0xffff00; + + bp->timer_interval = HZ; + + /* Disable WOL support if we are running on a SERDES chip. */ + if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) { + bp->phy_flags |= PHY_SERDES_FLAG; + bp->flags |= NO_WOL_FLAG; + } + + if (CHIP_ID(bp) == CHIP_ID_5706_A0) { + bp->tx_quick_cons_trip_int = + bp->tx_quick_cons_trip; + bp->tx_ticks_int = bp->tx_ticks; + bp->rx_quick_cons_trip_int = + bp->rx_quick_cons_trip; + bp->rx_ticks_int = bp->rx_ticks; + bp->comp_prod_trip_int = bp->comp_prod_trip; + bp->com_ticks_int = bp->com_ticks; + bp->cmd_ticks_int = bp->cmd_ticks; + } + + bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; + bp->req_line_speed = 0; + if (bp->phy_flags & PHY_SERDES_FLAG) { + bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; + } + else { + bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; + } + + bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX; + + return 0; + +err_out_unmap: + if (bp->regview) { + iounmap(bp->regview); + } + +err_out_release: + pci_release_regions(pdev); + +err_out_disable: + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + +err_out: + return rc; +} + +static int __devinit +bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + static int version_printed = 0; + struct net_device *dev = NULL; + struct bnx2 *bp; + int rc, i; + + if (version_printed++ == 0) + printk(KERN_INFO "%s", version); + + /* dev zeroed in init_etherdev */ + dev = alloc_etherdev(sizeof(*bp)); + + if (!dev) + return -ENOMEM; + + rc = bnx2_init_board(pdev, dev); + if (rc < 0) { + free_netdev(dev); + return rc; + } + + dev->open = bnx2_open; + dev->hard_start_xmit = bnx2_start_xmit; + dev->stop = bnx2_close; + dev->get_stats = bnx2_get_stats; + dev->set_multicast_list = bnx2_set_rx_mode; + dev->do_ioctl = bnx2_ioctl; + dev->set_mac_address = bnx2_change_mac_addr; + dev->change_mtu = bnx2_change_mtu; + dev->tx_timeout = bnx2_tx_timeout; + dev->watchdog_timeo = TX_TIMEOUT; +#ifdef BCM_VLAN + dev->vlan_rx_register = bnx2_vlan_rx_register; + dev->vlan_rx_kill_vid = bnx2_vlan_rx_kill_vid; +#endif + dev->poll = bnx2_poll; + dev->ethtool_ops = &bnx2_ethtool_ops; + dev->weight = 64; + + bp = dev->priv; + +#if defined(HAVE_POLL_CONTROLLER) || defined(CONFIG_NET_POLL_CONTROLLER) + dev->poll_controller = poll_bnx2; +#endif + + if ((rc = register_netdev(dev))) { + printk(KERN_ERR PFX "Cannot register net device\n"); + if (bp->regview) + iounmap(bp->regview); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); + free_netdev(dev); + return rc; + } + + pci_set_drvdata(pdev, dev); + + memcpy(dev->dev_addr, bp->mac_addr, 6); + bp->name = board_info[ent->driver_data].name, + printk(KERN_INFO "%s: %s (%c%d) PCI%s %s %dMHz found at mem %lx, " + "IRQ %d, ", + dev->name, + bp->name, + ((CHIP_ID(bp) & 0xf000) >> 12) + 'A', + ((CHIP_ID(bp) & 0x0ff0) >> 4), + ((bp->flags & PCIX_FLAG) ? "-X" : ""), + ((bp->flags & PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), + bp->bus_speed_mhz, + dev->base_addr, + bp->pdev->irq); + + printk("node addr "); + for (i = 0; i < 6; i++) + printk("%2.2x", dev->dev_addr[i]); + printk("\n"); + + dev->features |= NETIF_F_SG; + if (bp->flags & USING_DAC_FLAG) + dev->features |= NETIF_F_HIGHDMA; + dev->features |= NETIF_F_IP_CSUM; +#ifdef BCM_VLAN + dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; +#endif +#ifdef BCM_TSO + dev->features |= NETIF_F_TSO; +#endif + + netif_carrier_off(bp->dev); + + return 0; +} + +static void __devexit +bnx2_remove_one(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2 *bp = dev->priv; + + unregister_netdev(dev); + + if (bp->regview) + iounmap(bp->regview); + + free_netdev(dev); + pci_release_regions(pdev); + pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); +} + +static int +bnx2_suspend(struct pci_dev *pdev, u32 state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2 *bp = dev->priv; + u32 reset_code; + + if (!netif_running(dev)) + return 0; + + bnx2_netif_stop(bp); + netif_device_detach(dev); + del_timer_sync(&bp->timer); + if (bp->wol) + reset_code = BNX2_DRV_MSG_CODE_SUSPEND_WOL; + else + reset_code = BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL; + bnx2_reset_chip(bp, reset_code); + bnx2_free_skbs(bp); + bnx2_set_power_state(bp, state); + return 0; +} + +static int +bnx2_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct bnx2 *bp = dev->priv; + + if (!netif_running(dev)) + return 0; + + bnx2_set_power_state(bp, 0); + netif_device_attach(dev); + bnx2_init_nic(bp); + bnx2_netif_start(bp); + return 0; +} + +static struct pci_driver bnx2_pci_driver = { + name: DRV_MODULE_NAME, + id_table: bnx2_pci_tbl, + probe: bnx2_init_one, + remove: __devexit_p(bnx2_remove_one), + suspend: bnx2_suspend, + resume: bnx2_resume, +}; + +static int __init bnx2_init(void) +{ + return pci_module_init(&bnx2_pci_driver); +} + +static void __exit bnx2_cleanup(void) +{ + pci_unregister_driver(&bnx2_pci_driver); +} + +module_init(bnx2_init); +module_exit(bnx2_cleanup); + + + diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h new file mode 100644 index 000000000000..8214a2853d0d --- /dev/null +++ b/drivers/net/bnx2.h @@ -0,0 +1,4352 @@ +/* bnx2.h: Broadcom NX2 network driver. + * + * Copyright (c) 2004, 2005 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation. + * + * Written by: Michael Chan (mchan@broadcom.com) + */ + + +#ifndef BNX2_H +#define BNX2_H + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef NETIF_F_HW_VLAN_TX +#include +#define BCM_VLAN 1 +#endif +#ifdef NETIF_F_TSO +#include +#include +#include +#define BCM_TSO 1 +#endif +#include +#include + +/* Hardware data structures and register definitions automatically + * generated from RTL code. Do not modify. + */ + +/* + * tx_bd definition + */ +struct tx_bd { + u32 tx_bd_haddr_hi; + u32 tx_bd_haddr_lo; + u32 tx_bd_mss_nbytes; + u32 tx_bd_vlan_tag_flags; + #define TX_BD_FLAGS_CONN_FAULT (1<<0) + #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) + #define TX_BD_FLAGS_IP_CKSUM (1<<2) + #define TX_BD_FLAGS_VLAN_TAG (1<<3) + #define TX_BD_FLAGS_COAL_NOW (1<<4) + #define TX_BD_FLAGS_DONT_GEN_CRC (1<<5) + #define TX_BD_FLAGS_END (1<<6) + #define TX_BD_FLAGS_START (1<<7) + #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) + #define TX_BD_FLAGS_SW_FLAGS (1<<13) + #define TX_BD_FLAGS_SW_SNAP (1<<14) + #define TX_BD_FLAGS_SW_LSO (1<<15) + +}; + + +/* + * rx_bd definition + */ +struct rx_bd { + u32 rx_bd_haddr_hi; + u32 rx_bd_haddr_lo; + u32 rx_bd_len; + u32 rx_bd_flags; + #define RX_BD_FLAGS_NOPUSH (1<<0) + #define RX_BD_FLAGS_DUMMY (1<<1) + #define RX_BD_FLAGS_END (1<<2) + #define RX_BD_FLAGS_START (1<<3) + +}; + + +/* + * status_block definition + */ +struct status_block { + u32 status_attn_bits; + #define STATUS_ATTN_BITS_LINK_STATE (1L<<0) + #define STATUS_ATTN_BITS_TX_SCHEDULER_ABORT (1L<<1) + #define STATUS_ATTN_BITS_TX_BD_READ_ABORT (1L<<2) + #define STATUS_ATTN_BITS_TX_BD_CACHE_ABORT (1L<<3) + #define STATUS_ATTN_BITS_TX_PROCESSOR_ABORT (1L<<4) + #define STATUS_ATTN_BITS_TX_DMA_ABORT (1L<<5) + #define STATUS_ATTN_BITS_TX_PATCHUP_ABORT (1L<<6) + #define STATUS_ATTN_BITS_TX_ASSEMBLER_ABORT (1L<<7) + #define STATUS_ATTN_BITS_RX_PARSER_MAC_ABORT (1L<<8) + #define STATUS_ATTN_BITS_RX_PARSER_CATCHUP_ABORT (1L<<9) + #define STATUS_ATTN_BITS_RX_MBUF_ABORT (1L<<10) + #define STATUS_ATTN_BITS_RX_LOOKUP_ABORT (1L<<11) + #define STATUS_ATTN_BITS_RX_PROCESSOR_ABORT (1L<<12) + #define STATUS_ATTN_BITS_RX_V2P_ABORT (1L<<13) + #define STATUS_ATTN_BITS_RX_BD_CACHE_ABORT (1L<<14) + #define STATUS_ATTN_BITS_RX_DMA_ABORT (1L<<15) + #define STATUS_ATTN_BITS_COMPLETION_ABORT (1L<<16) + #define STATUS_ATTN_BITS_HOST_COALESCE_ABORT (1L<<17) + #define STATUS_ATTN_BITS_MAILBOX_QUEUE_ABORT (1L<<18) + #define STATUS_ATTN_BITS_CONTEXT_ABORT (1L<<19) + #define STATUS_ATTN_BITS_CMD_SCHEDULER_ABORT (1L<<20) + #define STATUS_ATTN_BITS_CMD_PROCESSOR_ABORT (1L<<21) + #define STATUS_ATTN_BITS_MGMT_PROCESSOR_ABORT (1L<<22) + #define STATUS_ATTN_BITS_MAC_ABORT (1L<<23) + #define STATUS_ATTN_BITS_TIMER_ABORT (1L<<24) + #define STATUS_ATTN_BITS_DMAE_ABORT (1L<<25) + #define STATUS_ATTN_BITS_FLSH_ABORT (1L<<26) + #define STATUS_ATTN_BITS_GRC_ABORT (1L<<27) + #define STATUS_ATTN_BITS_PARITY_ERROR (1L<<31) + + u32 status_attn_bits_ack; +#if defined(__BIG_ENDIAN) + u16 status_tx_quick_consumer_index0; + u16 status_tx_quick_consumer_index1; + u16 status_tx_quick_consumer_index2; + u16 status_tx_quick_consumer_index3; + u16 status_rx_quick_consumer_index0; + u16 status_rx_quick_consumer_index1; + u16 status_rx_quick_consumer_index2; + u16 status_rx_quick_consumer_index3; + u16 status_rx_quick_consumer_index4; + u16 status_rx_quick_consumer_index5; + u16 status_rx_quick_consumer_index6; + u16 status_rx_quick_consumer_index7; + u16 status_rx_quick_consumer_index8; + u16 status_rx_quick_consumer_index9; + u16 status_rx_quick_consumer_index10; + u16 status_rx_quick_consumer_index11; + u16 status_rx_quick_consumer_index12; + u16 status_rx_quick_consumer_index13; + u16 status_rx_quick_consumer_index14; + u16 status_rx_quick_consumer_index15; + u16 status_completion_producer_index; + u16 status_cmd_consumer_index; + u16 status_idx; + u16 status_unused; +#elif defined(__LITTLE_ENDIAN) + u16 status_tx_quick_consumer_index1; + u16 status_tx_quick_consumer_index0; + u16 status_tx_quick_consumer_index3; + u16 status_tx_quick_consumer_index2; + u16 status_rx_quick_consumer_index1; + u16 status_rx_quick_consumer_index0; + u16 status_rx_quick_consumer_index3; + u16 status_rx_quick_consumer_index2; + u16 status_rx_quick_consumer_index5; + u16 status_rx_quick_consumer_index4; + u16 status_rx_quick_consumer_index7; + u16 status_rx_quick_consumer_index6; + u16 status_rx_quick_consumer_index9; + u16 status_rx_quick_consumer_index8; + u16 status_rx_quick_consumer_index11; + u16 status_rx_quick_consumer_index10; + u16 status_rx_quick_consumer_index13; + u16 status_rx_quick_consumer_index12; + u16 status_rx_quick_consumer_index15; + u16 status_rx_quick_consumer_index14; + u16 status_cmd_consumer_index; + u16 status_completion_producer_index; + u16 status_unused; + u16 status_idx; +#endif +}; + + +/* + * statistics_block definition + */ +struct statistics_block { + u32 stat_IfHCInOctets_hi; + u32 stat_IfHCInOctets_lo; + u32 stat_IfHCInBadOctets_hi; + u32 stat_IfHCInBadOctets_lo; + u32 stat_IfHCOutOctets_hi; + u32 stat_IfHCOutOctets_lo; + u32 stat_IfHCOutBadOctets_hi; + u32 stat_IfHCOutBadOctets_lo; + u32 stat_IfHCInUcastPkts_hi; + u32 stat_IfHCInUcastPkts_lo; + u32 stat_IfHCInMulticastPkts_hi; + u32 stat_IfHCInMulticastPkts_lo; + u32 stat_IfHCInBroadcastPkts_hi; + u32 stat_IfHCInBroadcastPkts_lo; + u32 stat_IfHCOutUcastPkts_hi; + u32 stat_IfHCOutUcastPkts_lo; + u32 stat_IfHCOutMulticastPkts_hi; + u32 stat_IfHCOutMulticastPkts_lo; + u32 stat_IfHCOutBroadcastPkts_hi; + u32 stat_IfHCOutBroadcastPkts_lo; + u32 stat_emac_tx_stat_dot3statsinternalmactransmiterrors; + u32 stat_Dot3StatsCarrierSenseErrors; + u32 stat_Dot3StatsFCSErrors; + u32 stat_Dot3StatsAlignmentErrors; + u32 stat_Dot3StatsSingleCollisionFrames; + u32 stat_Dot3StatsMultipleCollisionFrames; + u32 stat_Dot3StatsDeferredTransmissions; + u32 stat_Dot3StatsExcessiveCollisions; + u32 stat_Dot3StatsLateCollisions; + u32 stat_EtherStatsCollisions; + u32 stat_EtherStatsFragments; + u32 stat_EtherStatsJabbers; + u32 stat_EtherStatsUndersizePkts; + u32 stat_EtherStatsOverrsizePkts; + u32 stat_EtherStatsPktsRx64Octets; + u32 stat_EtherStatsPktsRx65Octetsto127Octets; + u32 stat_EtherStatsPktsRx128Octetsto255Octets; + u32 stat_EtherStatsPktsRx256Octetsto511Octets; + u32 stat_EtherStatsPktsRx512Octetsto1023Octets; + u32 stat_EtherStatsPktsRx1024Octetsto1522Octets; + u32 stat_EtherStatsPktsRx1523Octetsto9022Octets; + u32 stat_EtherStatsPktsTx64Octets; + u32 stat_EtherStatsPktsTx65Octetsto127Octets; + u32 stat_EtherStatsPktsTx128Octetsto255Octets; + u32 stat_EtherStatsPktsTx256Octetsto511Octets; + u32 stat_EtherStatsPktsTx512Octetsto1023Octets; + u32 stat_EtherStatsPktsTx1024Octetsto1522Octets; + u32 stat_EtherStatsPktsTx1523Octetsto9022Octets; + u32 stat_XonPauseFramesReceived; + u32 stat_XoffPauseFramesReceived; + u32 stat_OutXonSent; + u32 stat_OutXoffSent; + u32 stat_FlowControlDone; + u32 stat_MacControlFramesReceived; + u32 stat_XoffStateEntered; + u32 stat_IfInFramesL2FilterDiscards; + u32 stat_IfInRuleCheckerDiscards; + u32 stat_IfInFTQDiscards; + u32 stat_IfInMBUFDiscards; + u32 stat_IfInRuleCheckerP4Hit; + u32 stat_CatchupInRuleCheckerDiscards; + u32 stat_CatchupInFTQDiscards; + u32 stat_CatchupInMBUFDiscards; + u32 stat_CatchupInRuleCheckerP4Hit; + u32 stat_GenStat00; + u32 stat_GenStat01; + u32 stat_GenStat02; + u32 stat_GenStat03; + u32 stat_GenStat04; + u32 stat_GenStat05; + u32 stat_GenStat06; + u32 stat_GenStat07; + u32 stat_GenStat08; + u32 stat_GenStat09; + u32 stat_GenStat10; + u32 stat_GenStat11; + u32 stat_GenStat12; + u32 stat_GenStat13; + u32 stat_GenStat14; + u32 stat_GenStat15; +}; + + +/* + * l2_fhdr definition + */ +struct l2_fhdr { +#if defined(__BIG_ENDIAN) + u16 l2_fhdr_errors; + u16 l2_fhdr_status; +#elif defined(__LITTLE_ENDIAN) + u16 l2_fhdr_status; + u16 l2_fhdr_errors; +#endif + #define L2_FHDR_ERRORS_BAD_CRC (1<<1) + #define L2_FHDR_ERRORS_PHY_DECODE (1<<2) + #define L2_FHDR_ERRORS_ALIGNMENT (1<<3) + #define L2_FHDR_ERRORS_TOO_SHORT (1<<4) + #define L2_FHDR_ERRORS_GIANT_FRAME (1<<5) + + #define L2_FHDR_STATUS_RULE_CLASS (0x7<<0) + #define L2_FHDR_STATUS_RULE_P2 (1<<3) + #define L2_FHDR_STATUS_RULE_P3 (1<<4) + #define L2_FHDR_STATUS_RULE_P4 (1<<5) + #define L2_FHDR_STATUS_L2_VLAN_TAG (1<<6) + #define L2_FHDR_STATUS_L2_LLC_SNAP (1<<7) + #define L2_FHDR_STATUS_RSS_HASH (1<<8) + #define L2_FHDR_STATUS_IP_DATAGRAM (1<<13) + #define L2_FHDR_STATUS_TCP_SEGMENT (1<<14) + #define L2_FHDR_STATUS_UDP_DATAGRAM (1<<15) + + u32 l2_fhdr_hash; +#if defined(__BIG_ENDIAN) + u16 l2_fhdr_pkt_len; + u16 l2_fhdr_vlan_tag; + u16 l2_fhdr_ip_xsum; + u16 l2_fhdr_tcp_udp_xsum; +#elif defined(__LITTLE_ENDIAN) + u16 l2_fhdr_vlan_tag; + u16 l2_fhdr_pkt_len; + u16 l2_fhdr_tcp_udp_xsum; + u16 l2_fhdr_ip_xsum; +#endif +}; + + +/* + * l2_context definition + */ +#define BNX2_L2CTX_TYPE 0x00000000 +#define BNX2_L2CTX_TYPE_SIZE_L2 ((0xc0/0x20)<<16) +#define BNX2_L2CTX_TYPE_TYPE (0xf<<28) +#define BNX2_L2CTX_TYPE_TYPE_EMPTY (0<<28) +#define BNX2_L2CTX_TYPE_TYPE_L2 (1<<28) + +#define BNX2_L2CTX_TX_HOST_BIDX 0x00000088 +#define BNX2_L2CTX_EST_NBD 0x00000088 +#define BNX2_L2CTX_CMD_TYPE 0x00000088 +#define BNX2_L2CTX_CMD_TYPE_TYPE (0xf<<24) +#define BNX2_L2CTX_CMD_TYPE_TYPE_L2 (0<<24) +#define BNX2_L2CTX_CMD_TYPE_TYPE_TCP (1<<24) + +#define BNX2_L2CTX_TX_HOST_BSEQ 0x00000090 +#define BNX2_L2CTX_TSCH_BSEQ 0x00000094 +#define BNX2_L2CTX_TBDR_BSEQ 0x00000098 +#define BNX2_L2CTX_TBDR_BOFF 0x0000009c +#define BNX2_L2CTX_TBDR_BIDX 0x0000009c +#define BNX2_L2CTX_TBDR_BHADDR_HI 0x000000a0 +#define BNX2_L2CTX_TBDR_BHADDR_LO 0x000000a4 +#define BNX2_L2CTX_TXP_BOFF 0x000000a8 +#define BNX2_L2CTX_TXP_BIDX 0x000000a8 +#define BNX2_L2CTX_TXP_BSEQ 0x000000ac + + +/* + * l2_bd_chain_context definition + */ +#define BNX2_L2CTX_BD_PRE_READ 0x00000000 +#define BNX2_L2CTX_CTX_SIZE 0x00000000 +#define BNX2_L2CTX_CTX_TYPE 0x00000000 +#define BNX2_L2CTX_CTX_TYPE_SIZE_L2 ((0x20/20)<<16) +#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE (0xf<<28) +#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_UNDEFINED (0<<28) +#define BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE (1<<28) + +#define BNX2_L2CTX_HOST_BDIDX 0x00000004 +#define BNX2_L2CTX_HOST_BSEQ 0x00000008 +#define BNX2_L2CTX_NX_BSEQ 0x0000000c +#define BNX2_L2CTX_NX_BDHADDR_HI 0x00000010 +#define BNX2_L2CTX_NX_BDHADDR_LO 0x00000014 +#define BNX2_L2CTX_NX_BDIDX 0x00000018 + + +/* + * pci_config_l definition + * offset: 0000 + */ +#define BNX2_PCICFG_MISC_CONFIG 0x00000068 +#define BNX2_PCICFG_MISC_CONFIG_TARGET_BYTE_SWAP (1L<<2) +#define BNX2_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP (1L<<3) +#define BNX2_PCICFG_MISC_CONFIG_CLOCK_CTL_ENA (1L<<5) +#define BNX2_PCICFG_MISC_CONFIG_TARGET_GRC_WORD_SWAP (1L<<6) +#define BNX2_PCICFG_MISC_CONFIG_REG_WINDOW_ENA (1L<<7) +#define BNX2_PCICFG_MISC_CONFIG_CORE_RST_REQ (1L<<8) +#define BNX2_PCICFG_MISC_CONFIG_CORE_RST_BSY (1L<<9) +#define BNX2_PCICFG_MISC_CONFIG_ASIC_METAL_REV (0xffL<<16) +#define BNX2_PCICFG_MISC_CONFIG_ASIC_BASE_REV (0xfL<<24) +#define BNX2_PCICFG_MISC_CONFIG_ASIC_ID (0xfL<<28) + +#define BNX2_PCICFG_MISC_STATUS 0x0000006c +#define BNX2_PCICFG_MISC_STATUS_INTA_VALUE (1L<<0) +#define BNX2_PCICFG_MISC_STATUS_32BIT_DET (1L<<1) +#define BNX2_PCICFG_MISC_STATUS_M66EN (1L<<2) +#define BNX2_PCICFG_MISC_STATUS_PCIX_DET (1L<<3) +#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED (0x3L<<4) +#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_66 (0L<<4) +#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_100 (1L<<4) +#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_133 (2L<<4) +#define BNX2_PCICFG_MISC_STATUS_PCIX_SPEED_PCI_MODE (3L<<4) + +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS 0x00000070 +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET (0xfL<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ (0L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ (1L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ (2L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ (3L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ (4L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ (5L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ (6L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ (7L<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW (0xfL<<0) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE (1L<<6) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT (1L<<7) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC (0x7L<<8) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF (0L<<8) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12 (1L<<8) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6 (2L<<8) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62 (4L<<8) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PLAY_DEAD (1L<<11) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED (0xfL<<12) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100 (0L<<12) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80 (1L<<12) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50 (2L<<12) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40 (4L<<12) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25 (8L<<12) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP (1L<<16) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_PLL_STOP (1L<<17) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED_18 (1L<<18) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_USE_SPD_DET (1L<<19) +#define BNX2_PCICFG_PCI_CLOCK_CONTROL_BITS_RESERVED (0xfffL<<20) + +#define BNX2_PCICFG_REG_WINDOW_ADDRESS 0x00000078 +#define BNX2_PCICFG_REG_WINDOW 0x00000080 +#define BNX2_PCICFG_INT_ACK_CMD 0x00000084 +#define BNX2_PCICFG_INT_ACK_CMD_INDEX (0xffffL<<0) +#define BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID (1L<<16) +#define BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM (1L<<17) +#define BNX2_PCICFG_INT_ACK_CMD_MASK_INT (1L<<18) + +#define BNX2_PCICFG_STATUS_BIT_SET_CMD 0x00000088 +#define BNX2_PCICFG_STATUS_BIT_CLEAR_CMD 0x0000008c +#define BNX2_PCICFG_MAILBOX_QUEUE_ADDR 0x00000090 +#define BNX2_PCICFG_MAILBOX_QUEUE_DATA 0x00000094 + + +/* + * pci_reg definition + * offset: 0x400 + */ +#define BNX2_PCI_GRC_WINDOW_ADDR 0x00000400 +#define BNX2_PCI_GRC_WINDOW_ADDR_PCI_GRC_WINDOW_ADDR_VALUE (0x3ffffL<<8) + +#define BNX2_PCI_CONFIG_1 0x00000404 +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY (0x7L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_OFF (0L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_16 (1L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_32 (2L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_64 (3L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_128 (4L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_256 (5L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_512 (6L<<8) +#define BNX2_PCI_CONFIG_1_READ_BOUNDARY_1024 (7L<<8) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY (0x7L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_OFF (0L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_16 (1L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_32 (2L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_64 (3L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_128 (4L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_256 (5L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_512 (6L<<11) +#define BNX2_PCI_CONFIG_1_WRITE_BOUNDARY_1024 (7L<<11) + +#define BNX2_PCI_CONFIG_2 0x00000408 +#define BNX2_PCI_CONFIG_2_BAR1_SIZE (0xfL<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_DISABLED (0L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_64K (1L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_128K (2L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_256K (3L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_512K (4L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_1M (5L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_2M (6L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_4M (7L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_8M (8L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_16M (9L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_32M (10L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_64M (11L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_128M (12L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_256M (13L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_512M (14L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_SIZE_1G (15L<<0) +#define BNX2_PCI_CONFIG_2_BAR1_64ENA (1L<<4) +#define BNX2_PCI_CONFIG_2_EXP_ROM_RETRY (1L<<5) +#define BNX2_PCI_CONFIG_2_CFG_CYCLE_RETRY (1L<<6) +#define BNX2_PCI_CONFIG_2_FIRST_CFG_DONE (1L<<7) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE (0xffL<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_DISABLED (0L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1K (1L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2K (2L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4K (3L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8K (4L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16K (5L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_32K (6L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_64K (7L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_128K (8L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_256K (9L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_512K (10L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_1M (11L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_2M (12L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_4M (13L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_8M (14L<<8) +#define BNX2_PCI_CONFIG_2_EXP_ROM_SIZE_16M (15L<<8) +#define BNX2_PCI_CONFIG_2_MAX_SPLIT_LIMIT (0x1fL<<16) +#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT (0x3L<<21) +#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_512 (0L<<21) +#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_1K (1L<<21) +#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_2K (2L<<21) +#define BNX2_PCI_CONFIG_2_MAX_READ_LIMIT_4K (3L<<21) +#define BNX2_PCI_CONFIG_2_FORCE_32_BIT_MSTR (1L<<23) +#define BNX2_PCI_CONFIG_2_FORCE_32_BIT_TGT (1L<<24) +#define BNX2_PCI_CONFIG_2_KEEP_REQ_ASSERT (1L<<25) + +#define BNX2_PCI_CONFIG_3 0x0000040c +#define BNX2_PCI_CONFIG_3_STICKY_BYTE (0xffL<<0) +#define BNX2_PCI_CONFIG_3_FORCE_PME (1L<<24) +#define BNX2_PCI_CONFIG_3_PME_STATUS (1L<<25) +#define BNX2_PCI_CONFIG_3_PME_ENABLE (1L<<26) +#define BNX2_PCI_CONFIG_3_PM_STATE (0x3L<<27) +#define BNX2_PCI_CONFIG_3_VAUX_PRESET (1L<<30) +#define BNX2_PCI_CONFIG_3_PCI_POWER (1L<<31) + +#define BNX2_PCI_PM_DATA_A 0x00000410 +#define BNX2_PCI_PM_DATA_A_PM_DATA_0_PRG (0xffL<<0) +#define BNX2_PCI_PM_DATA_A_PM_DATA_1_PRG (0xffL<<8) +#define BNX2_PCI_PM_DATA_A_PM_DATA_2_PRG (0xffL<<16) +#define BNX2_PCI_PM_DATA_A_PM_DATA_3_PRG (0xffL<<24) + +#define BNX2_PCI_PM_DATA_B 0x00000414 +#define BNX2_PCI_PM_DATA_B_PM_DATA_4_PRG (0xffL<<0) +#define BNX2_PCI_PM_DATA_B_PM_DATA_5_PRG (0xffL<<8) +#define BNX2_PCI_PM_DATA_B_PM_DATA_6_PRG (0xffL<<16) +#define BNX2_PCI_PM_DATA_B_PM_DATA_7_PRG (0xffL<<24) + +#define BNX2_PCI_SWAP_DIAG0 0x00000418 +#define BNX2_PCI_SWAP_DIAG1 0x0000041c +#define BNX2_PCI_EXP_ROM_ADDR 0x00000420 +#define BNX2_PCI_EXP_ROM_ADDR_ADDRESS (0x3fffffL<<2) +#define BNX2_PCI_EXP_ROM_ADDR_REQ (1L<<31) + +#define BNX2_PCI_EXP_ROM_DATA 0x00000424 +#define BNX2_PCI_VPD_INTF 0x00000428 +#define BNX2_PCI_VPD_INTF_INTF_REQ (1L<<0) + +#define BNX2_PCI_VPD_ADDR_FLAG 0x0000042c +#define BNX2_PCI_VPD_ADDR_FLAG_ADDRESS (0x1fff<<2) +#define BNX2_PCI_VPD_ADDR_FLAG_WR (1<<15) + +#define BNX2_PCI_VPD_DATA 0x00000430 +#define BNX2_PCI_ID_VAL1 0x00000434 +#define BNX2_PCI_ID_VAL1_DEVICE_ID (0xffffL<<0) +#define BNX2_PCI_ID_VAL1_VENDOR_ID (0xffffL<<16) + +#define BNX2_PCI_ID_VAL2 0x00000438 +#define BNX2_PCI_ID_VAL2_SUBSYSTEM_VENDOR_ID (0xffffL<<0) +#define BNX2_PCI_ID_VAL2_SUBSYSTEM_ID (0xffffL<<16) + +#define BNX2_PCI_ID_VAL3 0x0000043c +#define BNX2_PCI_ID_VAL3_CLASS_CODE (0xffffffL<<0) +#define BNX2_PCI_ID_VAL3_REVISION_ID (0xffL<<24) + +#define BNX2_PCI_ID_VAL4 0x00000440 +#define BNX2_PCI_ID_VAL4_CAP_ENA (0xfL<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_0 (0L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_1 (1L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_2 (2L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_3 (3L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_4 (4L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_5 (5L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_6 (6L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_7 (7L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_8 (8L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_9 (9L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_10 (10L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_11 (11L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_12 (12L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_13 (13L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_14 (14L<<0) +#define BNX2_PCI_ID_VAL4_CAP_ENA_15 (15L<<0) +#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG (0x3L<<6) +#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_0 (0L<<6) +#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_1 (1L<<6) +#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_2 (2L<<6) +#define BNX2_PCI_ID_VAL4_PM_SCALE_PRG_3 (3L<<6) +#define BNX2_PCI_ID_VAL4_MSI_LIMIT (0x7L<<9) +#define BNX2_PCI_ID_VAL4_MSI_ADVERTIZE (0x7L<<12) +#define BNX2_PCI_ID_VAL4_MSI_ENABLE (1L<<15) +#define BNX2_PCI_ID_VAL4_MAX_64_ADVERTIZE (1L<<16) +#define BNX2_PCI_ID_VAL4_MAX_133_ADVERTIZE (1L<<17) +#define BNX2_PCI_ID_VAL4_MAX_MEM_READ_SIZE (0x3L<<21) +#define BNX2_PCI_ID_VAL4_MAX_SPLIT_SIZE (0x7L<<23) +#define BNX2_PCI_ID_VAL4_MAX_CUMULATIVE_SIZE (0x7L<<26) + +#define BNX2_PCI_ID_VAL5 0x00000444 +#define BNX2_PCI_ID_VAL5_D1_SUPPORT (1L<<0) +#define BNX2_PCI_ID_VAL5_D2_SUPPORT (1L<<1) +#define BNX2_PCI_ID_VAL5_PME_IN_D0 (1L<<2) +#define BNX2_PCI_ID_VAL5_PME_IN_D1 (1L<<3) +#define BNX2_PCI_ID_VAL5_PME_IN_D2 (1L<<4) +#define BNX2_PCI_ID_VAL5_PME_IN_D3_HOT (1L<<5) + +#define BNX2_PCI_PCIX_EXTENDED_STATUS 0x00000448 +#define BNX2_PCI_PCIX_EXTENDED_STATUS_NO_SNOOP (1L<<8) +#define BNX2_PCI_PCIX_EXTENDED_STATUS_LONG_BURST (1L<<9) +#define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_CLASS (0xfL<<16) +#define BNX2_PCI_PCIX_EXTENDED_STATUS_SPLIT_COMP_MSG_IDX (0xffL<<24) + +#define BNX2_PCI_ID_VAL6 0x0000044c +#define BNX2_PCI_ID_VAL6_MAX_LAT (0xffL<<0) +#define BNX2_PCI_ID_VAL6_MIN_GNT (0xffL<<8) +#define BNX2_PCI_ID_VAL6_BIST (0xffL<<16) + +#define BNX2_PCI_MSI_DATA 0x00000450 +#define BNX2_PCI_MSI_DATA_PCI_MSI_DATA (0xffffL<<0) + +#define BNX2_PCI_MSI_ADDR_H 0x00000454 +#define BNX2_PCI_MSI_ADDR_L 0x00000458 + + +/* + * misc_reg definition + * offset: 0x800 + */ +#define BNX2_MISC_COMMAND 0x00000800 +#define BNX2_MISC_COMMAND_ENABLE_ALL (1L<<0) +#define BNX2_MISC_COMMAND_DISABLE_ALL (1L<<1) +#define BNX2_MISC_COMMAND_CORE_RESET (1L<<4) +#define BNX2_MISC_COMMAND_HARD_RESET (1L<<5) +#define BNX2_MISC_COMMAND_PAR_ERROR (1L<<8) +#define BNX2_MISC_COMMAND_PAR_ERR_RAM (0x7fL<<16) + +#define BNX2_MISC_CFG 0x00000804 +#define BNX2_MISC_CFG_PCI_GRC_TMOUT (1L<<0) +#define BNX2_MISC_CFG_NVM_WR_EN (0x3L<<1) +#define BNX2_MISC_CFG_NVM_WR_EN_PROTECT (0L<<1) +#define BNX2_MISC_CFG_NVM_WR_EN_PCI (1L<<1) +#define BNX2_MISC_CFG_NVM_WR_EN_ALLOW (2L<<1) +#define BNX2_MISC_CFG_NVM_WR_EN_ALLOW2 (3L<<1) +#define BNX2_MISC_CFG_BIST_EN (1L<<3) +#define BNX2_MISC_CFG_CK25_OUT_ALT_SRC (1L<<4) +#define BNX2_MISC_CFG_BYPASS_BSCAN (1L<<5) +#define BNX2_MISC_CFG_BYPASS_EJTAG (1L<<6) +#define BNX2_MISC_CFG_CLK_CTL_OVERRIDE (1L<<7) +#define BNX2_MISC_CFG_LEDMODE (0x3L<<8) +#define BNX2_MISC_CFG_LEDMODE_MAC (0L<<8) +#define BNX2_MISC_CFG_LEDMODE_GPHY1 (1L<<8) +#define BNX2_MISC_CFG_LEDMODE_GPHY2 (2L<<8) + +#define BNX2_MISC_ID 0x00000808 +#define BNX2_MISC_ID_BOND_ID (0xfL<<0) +#define BNX2_MISC_ID_CHIP_METAL (0xffL<<4) +#define BNX2_MISC_ID_CHIP_REV (0xfL<<12) +#define BNX2_MISC_ID_CHIP_NUM (0xffffL<<16) + +#define BNX2_MISC_ENABLE_STATUS_BITS 0x0000080c +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_SCHEDULER_ENABLE (1L<<0) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_READ_ENABLE (1L<<1) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_BD_CACHE_ENABLE (1L<<2) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_PROCESSOR_ENABLE (1L<<3) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_DMA_ENABLE (1L<<4) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_PATCHUP_ENABLE (1L<<5) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_HEADER_Q_ENABLE (1L<<7) +#define BNX2_MISC_ENABLE_STATUS_BITS_TX_ASSEMBLER_ENABLE (1L<<8) +#define BNX2_MISC_ENABLE_STATUS_BITS_EMAC_ENABLE (1L<<9) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_MAC_ENABLE (1L<<10) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_MBUF_ENABLE (1L<<12) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_LOOKUP_ENABLE (1L<<13) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_PROCESSOR_ENABLE (1L<<14) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE (1L<<15) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_BD_CACHE_ENABLE (1L<<16) +#define BNX2_MISC_ENABLE_STATUS_BITS_RX_DMA_ENABLE (1L<<17) +#define BNX2_MISC_ENABLE_STATUS_BITS_COMPLETION_ENABLE (1L<<18) +#define BNX2_MISC_ENABLE_STATUS_BITS_HOST_COALESCE_ENABLE (1L<<19) +#define BNX2_MISC_ENABLE_STATUS_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) +#define BNX2_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE (1L<<21) +#define BNX2_MISC_ENABLE_STATUS_BITS_CMD_SCHEDULER_ENABLE (1L<<22) +#define BNX2_MISC_ENABLE_STATUS_BITS_CMD_PROCESSOR_ENABLE (1L<<23) +#define BNX2_MISC_ENABLE_STATUS_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) +#define BNX2_MISC_ENABLE_STATUS_BITS_TIMER_ENABLE (1L<<25) +#define BNX2_MISC_ENABLE_STATUS_BITS_DMA_ENGINE_ENABLE (1L<<26) +#define BNX2_MISC_ENABLE_STATUS_BITS_UMP_ENABLE (1L<<27) + +#define BNX2_MISC_ENABLE_SET_BITS 0x00000810 +#define BNX2_MISC_ENABLE_SET_BITS_TX_SCHEDULER_ENABLE (1L<<0) +#define BNX2_MISC_ENABLE_SET_BITS_TX_BD_READ_ENABLE (1L<<1) +#define BNX2_MISC_ENABLE_SET_BITS_TX_BD_CACHE_ENABLE (1L<<2) +#define BNX2_MISC_ENABLE_SET_BITS_TX_PROCESSOR_ENABLE (1L<<3) +#define BNX2_MISC_ENABLE_SET_BITS_TX_DMA_ENABLE (1L<<4) +#define BNX2_MISC_ENABLE_SET_BITS_TX_PATCHUP_ENABLE (1L<<5) +#define BNX2_MISC_ENABLE_SET_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) +#define BNX2_MISC_ENABLE_SET_BITS_TX_HEADER_Q_ENABLE (1L<<7) +#define BNX2_MISC_ENABLE_SET_BITS_TX_ASSEMBLER_ENABLE (1L<<8) +#define BNX2_MISC_ENABLE_SET_BITS_EMAC_ENABLE (1L<<9) +#define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_MAC_ENABLE (1L<<10) +#define BNX2_MISC_ENABLE_SET_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) +#define BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE (1L<<12) +#define BNX2_MISC_ENABLE_SET_BITS_RX_LOOKUP_ENABLE (1L<<13) +#define BNX2_MISC_ENABLE_SET_BITS_RX_PROCESSOR_ENABLE (1L<<14) +#define BNX2_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE (1L<<15) +#define BNX2_MISC_ENABLE_SET_BITS_RX_BD_CACHE_ENABLE (1L<<16) +#define BNX2_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE (1L<<17) +#define BNX2_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE (1L<<18) +#define BNX2_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE (1L<<19) +#define BNX2_MISC_ENABLE_SET_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) +#define BNX2_MISC_ENABLE_SET_BITS_CONTEXT_ENABLE (1L<<21) +#define BNX2_MISC_ENABLE_SET_BITS_CMD_SCHEDULER_ENABLE (1L<<22) +#define BNX2_MISC_ENABLE_SET_BITS_CMD_PROCESSOR_ENABLE (1L<<23) +#define BNX2_MISC_ENABLE_SET_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) +#define BNX2_MISC_ENABLE_SET_BITS_TIMER_ENABLE (1L<<25) +#define BNX2_MISC_ENABLE_SET_BITS_DMA_ENGINE_ENABLE (1L<<26) +#define BNX2_MISC_ENABLE_SET_BITS_UMP_ENABLE (1L<<27) + +#define BNX2_MISC_ENABLE_CLR_BITS 0x00000814 +#define BNX2_MISC_ENABLE_CLR_BITS_TX_SCHEDULER_ENABLE (1L<<0) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_READ_ENABLE (1L<<1) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_BD_CACHE_ENABLE (1L<<2) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_PROCESSOR_ENABLE (1L<<3) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE (1L<<4) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_PATCHUP_ENABLE (1L<<5) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_HEADER_Q_ENABLE (1L<<7) +#define BNX2_MISC_ENABLE_CLR_BITS_TX_ASSEMBLER_ENABLE (1L<<8) +#define BNX2_MISC_ENABLE_CLR_BITS_EMAC_ENABLE (1L<<9) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_MAC_ENABLE (1L<<10) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_MBUF_ENABLE (1L<<12) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_LOOKUP_ENABLE (1L<<13) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_PROCESSOR_ENABLE (1L<<14) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_V2P_ENABLE (1L<<15) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_BD_CACHE_ENABLE (1L<<16) +#define BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE (1L<<17) +#define BNX2_MISC_ENABLE_CLR_BITS_COMPLETION_ENABLE (1L<<18) +#define BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE (1L<<19) +#define BNX2_MISC_ENABLE_CLR_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) +#define BNX2_MISC_ENABLE_CLR_BITS_CONTEXT_ENABLE (1L<<21) +#define BNX2_MISC_ENABLE_CLR_BITS_CMD_SCHEDULER_ENABLE (1L<<22) +#define BNX2_MISC_ENABLE_CLR_BITS_CMD_PROCESSOR_ENABLE (1L<<23) +#define BNX2_MISC_ENABLE_CLR_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) +#define BNX2_MISC_ENABLE_CLR_BITS_TIMER_ENABLE (1L<<25) +#define BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE (1L<<26) +#define BNX2_MISC_ENABLE_CLR_BITS_UMP_ENABLE (1L<<27) + +#define BNX2_MISC_CLOCK_CONTROL_BITS 0x00000818 +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET (0xfL<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ (0L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ (1L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ (2L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ (3L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ (4L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ (5L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ (6L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ (7L<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW (0xfL<<0) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_DISABLE (1L<<6) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT (1L<<7) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC (0x7L<<8) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_UNDEF (0L<<8) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_12 (1L<<8) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_6 (2L<<8) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_ALT_SRC_62 (4L<<8) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PLAY_DEAD (1L<<11) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED (0xfL<<12) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_100 (0L<<12) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_80 (1L<<12) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_50 (2L<<12) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_40 (4L<<12) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_SPEED_25 (8L<<12) +#define BNX2_MISC_CLOCK_CONTROL_BITS_CORE_CLK_PLL_STOP (1L<<16) +#define BNX2_MISC_CLOCK_CONTROL_BITS_PCI_PLL_STOP (1L<<17) +#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED_18 (1L<<18) +#define BNX2_MISC_CLOCK_CONTROL_BITS_USE_SPD_DET (1L<<19) +#define BNX2_MISC_CLOCK_CONTROL_BITS_RESERVED (0xfffL<<20) + +#define BNX2_MISC_GPIO 0x0000081c +#define BNX2_MISC_GPIO_VALUE (0xffL<<0) +#define BNX2_MISC_GPIO_SET (0xffL<<8) +#define BNX2_MISC_GPIO_CLR (0xffL<<16) +#define BNX2_MISC_GPIO_FLOAT (0xffL<<24) + +#define BNX2_MISC_GPIO_INT 0x00000820 +#define BNX2_MISC_GPIO_INT_INT_STATE (0xfL<<0) +#define BNX2_MISC_GPIO_INT_OLD_VALUE (0xfL<<8) +#define BNX2_MISC_GPIO_INT_OLD_SET (0xfL<<16) +#define BNX2_MISC_GPIO_INT_OLD_CLR (0xfL<<24) + +#define BNX2_MISC_CONFIG_LFSR 0x00000824 +#define BNX2_MISC_CONFIG_LFSR_DIV (0xffffL<<0) + +#define BNX2_MISC_LFSR_MASK_BITS 0x00000828 +#define BNX2_MISC_LFSR_MASK_BITS_TX_SCHEDULER_ENABLE (1L<<0) +#define BNX2_MISC_LFSR_MASK_BITS_TX_BD_READ_ENABLE (1L<<1) +#define BNX2_MISC_LFSR_MASK_BITS_TX_BD_CACHE_ENABLE (1L<<2) +#define BNX2_MISC_LFSR_MASK_BITS_TX_PROCESSOR_ENABLE (1L<<3) +#define BNX2_MISC_LFSR_MASK_BITS_TX_DMA_ENABLE (1L<<4) +#define BNX2_MISC_LFSR_MASK_BITS_TX_PATCHUP_ENABLE (1L<<5) +#define BNX2_MISC_LFSR_MASK_BITS_TX_PAYLOAD_Q_ENABLE (1L<<6) +#define BNX2_MISC_LFSR_MASK_BITS_TX_HEADER_Q_ENABLE (1L<<7) +#define BNX2_MISC_LFSR_MASK_BITS_TX_ASSEMBLER_ENABLE (1L<<8) +#define BNX2_MISC_LFSR_MASK_BITS_EMAC_ENABLE (1L<<9) +#define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_MAC_ENABLE (1L<<10) +#define BNX2_MISC_LFSR_MASK_BITS_RX_PARSER_CATCHUP_ENABLE (1L<<11) +#define BNX2_MISC_LFSR_MASK_BITS_RX_MBUF_ENABLE (1L<<12) +#define BNX2_MISC_LFSR_MASK_BITS_RX_LOOKUP_ENABLE (1L<<13) +#define BNX2_MISC_LFSR_MASK_BITS_RX_PROCESSOR_ENABLE (1L<<14) +#define BNX2_MISC_LFSR_MASK_BITS_RX_V2P_ENABLE (1L<<15) +#define BNX2_MISC_LFSR_MASK_BITS_RX_BD_CACHE_ENABLE (1L<<16) +#define BNX2_MISC_LFSR_MASK_BITS_RX_DMA_ENABLE (1L<<17) +#define BNX2_MISC_LFSR_MASK_BITS_COMPLETION_ENABLE (1L<<18) +#define BNX2_MISC_LFSR_MASK_BITS_HOST_COALESCE_ENABLE (1L<<19) +#define BNX2_MISC_LFSR_MASK_BITS_MAILBOX_QUEUE_ENABLE (1L<<20) +#define BNX2_MISC_LFSR_MASK_BITS_CONTEXT_ENABLE (1L<<21) +#define BNX2_MISC_LFSR_MASK_BITS_CMD_SCHEDULER_ENABLE (1L<<22) +#define BNX2_MISC_LFSR_MASK_BITS_CMD_PROCESSOR_ENABLE (1L<<23) +#define BNX2_MISC_LFSR_MASK_BITS_MGMT_PROCESSOR_ENABLE (1L<<24) +#define BNX2_MISC_LFSR_MASK_BITS_TIMER_ENABLE (1L<<25) +#define BNX2_MISC_LFSR_MASK_BITS_DMA_ENGINE_ENABLE (1L<<26) +#define BNX2_MISC_LFSR_MASK_BITS_UMP_ENABLE (1L<<27) + +#define BNX2_MISC_ARB_REQ0 0x0000082c +#define BNX2_MISC_ARB_REQ1 0x00000830 +#define BNX2_MISC_ARB_REQ2 0x00000834 +#define BNX2_MISC_ARB_REQ3 0x00000838 +#define BNX2_MISC_ARB_REQ4 0x0000083c +#define BNX2_MISC_ARB_FREE0 0x00000840 +#define BNX2_MISC_ARB_FREE1 0x00000844 +#define BNX2_MISC_ARB_FREE2 0x00000848 +#define BNX2_MISC_ARB_FREE3 0x0000084c +#define BNX2_MISC_ARB_FREE4 0x00000850 +#define BNX2_MISC_ARB_REQ_STATUS0 0x00000854 +#define BNX2_MISC_ARB_REQ_STATUS1 0x00000858 +#define BNX2_MISC_ARB_REQ_STATUS2 0x0000085c +#define BNX2_MISC_ARB_REQ_STATUS3 0x00000860 +#define BNX2_MISC_ARB_REQ_STATUS4 0x00000864 +#define BNX2_MISC_ARB_GNT0 0x00000868 +#define BNX2_MISC_ARB_GNT0_0 (0x7L<<0) +#define BNX2_MISC_ARB_GNT0_1 (0x7L<<4) +#define BNX2_MISC_ARB_GNT0_2 (0x7L<<8) +#define BNX2_MISC_ARB_GNT0_3 (0x7L<<12) +#define BNX2_MISC_ARB_GNT0_4 (0x7L<<16) +#define BNX2_MISC_ARB_GNT0_5 (0x7L<<20) +#define BNX2_MISC_ARB_GNT0_6 (0x7L<<24) +#define BNX2_MISC_ARB_GNT0_7 (0x7L<<28) + +#define BNX2_MISC_ARB_GNT1 0x0000086c +#define BNX2_MISC_ARB_GNT1_8 (0x7L<<0) +#define BNX2_MISC_ARB_GNT1_9 (0x7L<<4) +#define BNX2_MISC_ARB_GNT1_10 (0x7L<<8) +#define BNX2_MISC_ARB_GNT1_11 (0x7L<<12) +#define BNX2_MISC_ARB_GNT1_12 (0x7L<<16) +#define BNX2_MISC_ARB_GNT1_13 (0x7L<<20) +#define BNX2_MISC_ARB_GNT1_14 (0x7L<<24) +#define BNX2_MISC_ARB_GNT1_15 (0x7L<<28) + +#define BNX2_MISC_ARB_GNT2 0x00000870 +#define BNX2_MISC_ARB_GNT2_16 (0x7L<<0) +#define BNX2_MISC_ARB_GNT2_17 (0x7L<<4) +#define BNX2_MISC_ARB_GNT2_18 (0x7L<<8) +#define BNX2_MISC_ARB_GNT2_19 (0x7L<<12) +#define BNX2_MISC_ARB_GNT2_20 (0x7L<<16) +#define BNX2_MISC_ARB_GNT2_21 (0x7L<<20) +#define BNX2_MISC_ARB_GNT2_22 (0x7L<<24) +#define BNX2_MISC_ARB_GNT2_23 (0x7L<<28) + +#define BNX2_MISC_ARB_GNT3 0x00000874 +#define BNX2_MISC_ARB_GNT3_24 (0x7L<<0) +#define BNX2_MISC_ARB_GNT3_25 (0x7L<<4) +#define BNX2_MISC_ARB_GNT3_26 (0x7L<<8) +#define BNX2_MISC_ARB_GNT3_27 (0x7L<<12) +#define BNX2_MISC_ARB_GNT3_28 (0x7L<<16) +#define BNX2_MISC_ARB_GNT3_29 (0x7L<<20) +#define BNX2_MISC_ARB_GNT3_30 (0x7L<<24) +#define BNX2_MISC_ARB_GNT3_31 (0x7L<<28) + +#define BNX2_MISC_PRBS_CONTROL 0x00000878 +#define BNX2_MISC_PRBS_CONTROL_EN (1L<<0) +#define BNX2_MISC_PRBS_CONTROL_RSTB (1L<<1) +#define BNX2_MISC_PRBS_CONTROL_INV (1L<<2) +#define BNX2_MISC_PRBS_CONTROL_ERR_CLR (1L<<3) +#define BNX2_MISC_PRBS_CONTROL_ORDER (0x3L<<4) +#define BNX2_MISC_PRBS_CONTROL_ORDER_7TH (0L<<4) +#define BNX2_MISC_PRBS_CONTROL_ORDER_15TH (1L<<4) +#define BNX2_MISC_PRBS_CONTROL_ORDER_23RD (2L<<4) +#define BNX2_MISC_PRBS_CONTROL_ORDER_31ST (3L<<4) + +#define BNX2_MISC_PRBS_STATUS 0x0000087c +#define BNX2_MISC_PRBS_STATUS_LOCK (1L<<0) +#define BNX2_MISC_PRBS_STATUS_STKY (1L<<1) +#define BNX2_MISC_PRBS_STATUS_ERRORS (0x3fffL<<2) +#define BNX2_MISC_PRBS_STATUS_STATE (0xfL<<16) + +#define BNX2_MISC_SM_ASF_CONTROL 0x00000880 +#define BNX2_MISC_SM_ASF_CONTROL_ASF_RST (1L<<0) +#define BNX2_MISC_SM_ASF_CONTROL_TSC_EN (1L<<1) +#define BNX2_MISC_SM_ASF_CONTROL_WG_TO (1L<<2) +#define BNX2_MISC_SM_ASF_CONTROL_HB_TO (1L<<3) +#define BNX2_MISC_SM_ASF_CONTROL_PA_TO (1L<<4) +#define BNX2_MISC_SM_ASF_CONTROL_PL_TO (1L<<5) +#define BNX2_MISC_SM_ASF_CONTROL_RT_TO (1L<<6) +#define BNX2_MISC_SM_ASF_CONTROL_SMB_EVENT (1L<<7) +#define BNX2_MISC_SM_ASF_CONTROL_RES (0xfL<<8) +#define BNX2_MISC_SM_ASF_CONTROL_SMB_EN (1L<<12) +#define BNX2_MISC_SM_ASF_CONTROL_SMB_BB_EN (1L<<13) +#define BNX2_MISC_SM_ASF_CONTROL_SMB_NO_ADDR_FILT (1L<<14) +#define BNX2_MISC_SM_ASF_CONTROL_SMB_AUTOREAD (1L<<15) +#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR1 (0x3fL<<16) +#define BNX2_MISC_SM_ASF_CONTROL_NIC_SMB_ADDR2 (0x3fL<<24) +#define BNX2_MISC_SM_ASF_CONTROL_EN_NIC_SMB_ADDR_0 (1L<<30) +#define BNX2_MISC_SM_ASF_CONTROL_SMB_EARLY_ATTN (1L<<31) + +#define BNX2_MISC_SMB_IN 0x00000884 +#define BNX2_MISC_SMB_IN_DAT_IN (0xffL<<0) +#define BNX2_MISC_SMB_IN_RDY (1L<<8) +#define BNX2_MISC_SMB_IN_DONE (1L<<9) +#define BNX2_MISC_SMB_IN_FIRSTBYTE (1L<<10) +#define BNX2_MISC_SMB_IN_STATUS (0x7L<<11) +#define BNX2_MISC_SMB_IN_STATUS_OK (0x0L<<11) +#define BNX2_MISC_SMB_IN_STATUS_PEC (0x1L<<11) +#define BNX2_MISC_SMB_IN_STATUS_OFLOW (0x2L<<11) +#define BNX2_MISC_SMB_IN_STATUS_STOP (0x3L<<11) +#define BNX2_MISC_SMB_IN_STATUS_TIMEOUT (0x4L<<11) + +#define BNX2_MISC_SMB_OUT 0x00000888 +#define BNX2_MISC_SMB_OUT_DAT_OUT (0xffL<<0) +#define BNX2_MISC_SMB_OUT_RDY (1L<<8) +#define BNX2_MISC_SMB_OUT_START (1L<<9) +#define BNX2_MISC_SMB_OUT_LAST (1L<<10) +#define BNX2_MISC_SMB_OUT_ACC_TYPE (1L<<11) +#define BNX2_MISC_SMB_OUT_ENB_PEC (1L<<12) +#define BNX2_MISC_SMB_OUT_GET_RX_LEN (1L<<13) +#define BNX2_MISC_SMB_OUT_SMB_READ_LEN (0x3fL<<14) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS (0xfL<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_OK (0L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_NACK (1L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_NACK (9L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_UFLOW (2L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_STOP (3L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_TIMEOUT (4L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_FIRST_LOST (5L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_SUB_LOST (0xdL<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_STATUS_BADACK (0x6L<<20) +#define BNX2_MISC_SMB_OUT_SMB_OUT_SLAVEMODE (1L<<24) +#define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_EN (1L<<25) +#define BNX2_MISC_SMB_OUT_SMB_OUT_DAT_IN (1L<<26) +#define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_EN (1L<<27) +#define BNX2_MISC_SMB_OUT_SMB_OUT_CLK_IN (1L<<28) + +#define BNX2_MISC_SMB_WATCHDOG 0x0000088c +#define BNX2_MISC_SMB_WATCHDOG_WATCHDOG (0xffffL<<0) + +#define BNX2_MISC_SMB_HEARTBEAT 0x00000890 +#define BNX2_MISC_SMB_HEARTBEAT_HEARTBEAT (0xffffL<<0) + +#define BNX2_MISC_SMB_POLL_ASF 0x00000894 +#define BNX2_MISC_SMB_POLL_ASF_POLL_ASF (0xffffL<<0) + +#define BNX2_MISC_SMB_POLL_LEGACY 0x00000898 +#define BNX2_MISC_SMB_POLL_LEGACY_POLL_LEGACY (0xffffL<<0) + +#define BNX2_MISC_SMB_RETRAN 0x0000089c +#define BNX2_MISC_SMB_RETRAN_RETRAN (0xffL<<0) + +#define BNX2_MISC_SMB_TIMESTAMP 0x000008a0 +#define BNX2_MISC_SMB_TIMESTAMP_TIMESTAMP (0xffffffffL<<0) + +#define BNX2_MISC_PERR_ENA0 0x000008a4 +#define BNX2_MISC_PERR_ENA0_COM_MISC_CTXC (1L<<0) +#define BNX2_MISC_PERR_ENA0_COM_MISC_REGF (1L<<1) +#define BNX2_MISC_PERR_ENA0_COM_MISC_SCPAD (1L<<2) +#define BNX2_MISC_PERR_ENA0_CP_MISC_CTXC (1L<<3) +#define BNX2_MISC_PERR_ENA0_CP_MISC_REGF (1L<<4) +#define BNX2_MISC_PERR_ENA0_CP_MISC_SCPAD (1L<<5) +#define BNX2_MISC_PERR_ENA0_CS_MISC_TMEM (1L<<6) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM0 (1L<<7) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM1 (1L<<8) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM2 (1L<<9) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM3 (1L<<10) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM4 (1L<<11) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_ACCM5 (1L<<12) +#define BNX2_MISC_PERR_ENA0_CTX_MISC_PGTBL (1L<<13) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR0 (1L<<14) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR1 (1L<<15) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR2 (1L<<16) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR3 (1L<<17) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DR4 (1L<<18) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW0 (1L<<19) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW1 (1L<<20) +#define BNX2_MISC_PERR_ENA0_DMAE_MISC_DW2 (1L<<21) +#define BNX2_MISC_PERR_ENA0_HC_MISC_DMA (1L<<22) +#define BNX2_MISC_PERR_ENA0_MCP_MISC_REGF (1L<<23) +#define BNX2_MISC_PERR_ENA0_MCP_MISC_SCPAD (1L<<24) +#define BNX2_MISC_PERR_ENA0_MQ_MISC_CTX (1L<<25) +#define BNX2_MISC_PERR_ENA0_RBDC_MISC (1L<<26) +#define BNX2_MISC_PERR_ENA0_RBUF_MISC_MB (1L<<27) +#define BNX2_MISC_PERR_ENA0_RBUF_MISC_PTR (1L<<28) +#define BNX2_MISC_PERR_ENA0_RDE_MISC_RPC (1L<<29) +#define BNX2_MISC_PERR_ENA0_RDE_MISC_RPM (1L<<30) +#define BNX2_MISC_PERR_ENA0_RV2P_MISC_CB0REGS (1L<<31) + +#define BNX2_MISC_PERR_ENA1 0x000008a8 +#define BNX2_MISC_PERR_ENA1_RV2P_MISC_CB1REGS (1L<<0) +#define BNX2_MISC_PERR_ENA1_RV2P_MISC_P1IRAM (1L<<1) +#define BNX2_MISC_PERR_ENA1_RV2P_MISC_P2IRAM (1L<<2) +#define BNX2_MISC_PERR_ENA1_RXP_MISC_CTXC (1L<<3) +#define BNX2_MISC_PERR_ENA1_RXP_MISC_REGF (1L<<4) +#define BNX2_MISC_PERR_ENA1_RXP_MISC_SCPAD (1L<<5) +#define BNX2_MISC_PERR_ENA1_RXP_MISC_RBUFC (1L<<6) +#define BNX2_MISC_PERR_ENA1_TBDC_MISC (1L<<7) +#define BNX2_MISC_PERR_ENA1_TDMA_MISC (1L<<8) +#define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB0 (1L<<9) +#define BNX2_MISC_PERR_ENA1_THBUF_MISC_MB1 (1L<<10) +#define BNX2_MISC_PERR_ENA1_TPAT_MISC_REGF (1L<<11) +#define BNX2_MISC_PERR_ENA1_TPAT_MISC_SCPAD (1L<<12) +#define BNX2_MISC_PERR_ENA1_TPBUF_MISC_MB (1L<<13) +#define BNX2_MISC_PERR_ENA1_TSCH_MISC_LR (1L<<14) +#define BNX2_MISC_PERR_ENA1_TXP_MISC_CTXC (1L<<15) +#define BNX2_MISC_PERR_ENA1_TXP_MISC_REGF (1L<<16) +#define BNX2_MISC_PERR_ENA1_TXP_MISC_SCPAD (1L<<17) +#define BNX2_MISC_PERR_ENA1_UMP_MISC_FIORX (1L<<18) +#define BNX2_MISC_PERR_ENA1_UMP_MISC_FIOTX (1L<<19) +#define BNX2_MISC_PERR_ENA1_UMP_MISC_RX (1L<<20) +#define BNX2_MISC_PERR_ENA1_UMP_MISC_TX (1L<<21) +#define BNX2_MISC_PERR_ENA1_RDMAQ_MISC (1L<<22) +#define BNX2_MISC_PERR_ENA1_CSQ_MISC (1L<<23) +#define BNX2_MISC_PERR_ENA1_CPQ_MISC (1L<<24) +#define BNX2_MISC_PERR_ENA1_MCPQ_MISC (1L<<25) +#define BNX2_MISC_PERR_ENA1_RV2PMQ_MISC (1L<<26) +#define BNX2_MISC_PERR_ENA1_RV2PPQ_MISC (1L<<27) +#define BNX2_MISC_PERR_ENA1_RV2PTQ_MISC (1L<<28) +#define BNX2_MISC_PERR_ENA1_RXPQ_MISC (1L<<29) +#define BNX2_MISC_PERR_ENA1_RXPCQ_MISC (1L<<30) +#define BNX2_MISC_PERR_ENA1_RLUPQ_MISC (1L<<31) + +#define BNX2_MISC_PERR_ENA2 0x000008ac +#define BNX2_MISC_PERR_ENA2_COMQ_MISC (1L<<0) +#define BNX2_MISC_PERR_ENA2_COMXQ_MISC (1L<<1) +#define BNX2_MISC_PERR_ENA2_COMTQ_MISC (1L<<2) +#define BNX2_MISC_PERR_ENA2_TSCHQ_MISC (1L<<3) +#define BNX2_MISC_PERR_ENA2_TBDRQ_MISC (1L<<4) +#define BNX2_MISC_PERR_ENA2_TXPQ_MISC (1L<<5) +#define BNX2_MISC_PERR_ENA2_TDMAQ_MISC (1L<<6) +#define BNX2_MISC_PERR_ENA2_TPATQ_MISC (1L<<7) +#define BNX2_MISC_PERR_ENA2_TASQ_MISC (1L<<8) + +#define BNX2_MISC_DEBUG_VECTOR_SEL 0x000008b0 +#define BNX2_MISC_DEBUG_VECTOR_SEL_0 (0xfffL<<0) +#define BNX2_MISC_DEBUG_VECTOR_SEL_1 (0xfffL<<12) + +#define BNX2_MISC_VREG_CONTROL 0x000008b4 +#define BNX2_MISC_VREG_CONTROL_1_2 (0xfL<<0) +#define BNX2_MISC_VREG_CONTROL_2_5 (0xfL<<4) + +#define BNX2_MISC_FINAL_CLK_CTL_VAL 0x000008b8 +#define BNX2_MISC_FINAL_CLK_CTL_VAL_MISC_FINAL_CLK_CTL_VAL (0x3ffffffL<<6) + +#define BNX2_MISC_UNUSED0 0x000008bc + + +/* + * nvm_reg definition + * offset: 0x6400 + */ +#define BNX2_NVM_COMMAND 0x00006400 +#define BNX2_NVM_COMMAND_RST (1L<<0) +#define BNX2_NVM_COMMAND_DONE (1L<<3) +#define BNX2_NVM_COMMAND_DOIT (1L<<4) +#define BNX2_NVM_COMMAND_WR (1L<<5) +#define BNX2_NVM_COMMAND_ERASE (1L<<6) +#define BNX2_NVM_COMMAND_FIRST (1L<<7) +#define BNX2_NVM_COMMAND_LAST (1L<<8) +#define BNX2_NVM_COMMAND_WREN (1L<<16) +#define BNX2_NVM_COMMAND_WRDI (1L<<17) +#define BNX2_NVM_COMMAND_EWSR (1L<<18) +#define BNX2_NVM_COMMAND_WRSR (1L<<19) + +#define BNX2_NVM_STATUS 0x00006404 +#define BNX2_NVM_STATUS_PI_FSM_STATE (0xfL<<0) +#define BNX2_NVM_STATUS_EE_FSM_STATE (0xfL<<4) +#define BNX2_NVM_STATUS_EQ_FSM_STATE (0xfL<<8) + +#define BNX2_NVM_WRITE 0x00006408 +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE (0xffffffffL<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_BIT_BANG (0L<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EECLK (1L<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_EEDATA (2L<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SCLK (4L<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_CS_B (8L<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SO (16L<<0) +#define BNX2_NVM_WRITE_NVM_WRITE_VALUE_SI (32L<<0) + +#define BNX2_NVM_ADDR 0x0000640c +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE (0xffffffL<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_BIT_BANG (0L<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EECLK (1L<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_EEDATA (2L<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SCLK (4L<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_CS_B (8L<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SO (16L<<0) +#define BNX2_NVM_ADDR_NVM_ADDR_VALUE_SI (32L<<0) + +#define BNX2_NVM_READ 0x00006410 +#define BNX2_NVM_READ_NVM_READ_VALUE (0xffffffffL<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_BIT_BANG (0L<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_EECLK (1L<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_EEDATA (2L<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_SCLK (4L<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_CS_B (8L<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_SO (16L<<0) +#define BNX2_NVM_READ_NVM_READ_VALUE_SI (32L<<0) + +#define BNX2_NVM_CFG1 0x00006414 +#define BNX2_NVM_CFG1_FLASH_MODE (1L<<0) +#define BNX2_NVM_CFG1_BUFFER_MODE (1L<<1) +#define BNX2_NVM_CFG1_PASS_MODE (1L<<2) +#define BNX2_NVM_CFG1_BITBANG_MODE (1L<<3) +#define BNX2_NVM_CFG1_STATUS_BIT (0x7L<<4) +#define BNX2_NVM_CFG1_STATUS_BIT_FLASH_RDY (0L<<4) +#define BNX2_NVM_CFG1_STATUS_BIT_BUFFER_RDY (7L<<4) +#define BNX2_NVM_CFG1_SPI_CLK_DIV (0xfL<<7) +#define BNX2_NVM_CFG1_SEE_CLK_DIV (0x7ffL<<11) +#define BNX2_NVM_CFG1_PROTECT_MODE (1L<<24) +#define BNX2_NVM_CFG1_FLASH_SIZE (1L<<25) +#define BNX2_NVM_CFG1_COMPAT_BYPASSS (1L<<31) + +#define BNX2_NVM_CFG2 0x00006418 +#define BNX2_NVM_CFG2_ERASE_CMD (0xffL<<0) +#define BNX2_NVM_CFG2_DUMMY (0xffL<<8) +#define BNX2_NVM_CFG2_STATUS_CMD (0xffL<<16) + +#define BNX2_NVM_CFG3 0x0000641c +#define BNX2_NVM_CFG3_BUFFER_RD_CMD (0xffL<<0) +#define BNX2_NVM_CFG3_WRITE_CMD (0xffL<<8) +#define BNX2_NVM_CFG3_BUFFER_WRITE_CMD (0xffL<<16) +#define BNX2_NVM_CFG3_READ_CMD (0xffL<<24) + +#define BNX2_NVM_SW_ARB 0x00006420 +#define BNX2_NVM_SW_ARB_ARB_REQ_SET0 (1L<<0) +#define BNX2_NVM_SW_ARB_ARB_REQ_SET1 (1L<<1) +#define BNX2_NVM_SW_ARB_ARB_REQ_SET2 (1L<<2) +#define BNX2_NVM_SW_ARB_ARB_REQ_SET3 (1L<<3) +#define BNX2_NVM_SW_ARB_ARB_REQ_CLR0 (1L<<4) +#define BNX2_NVM_SW_ARB_ARB_REQ_CLR1 (1L<<5) +#define BNX2_NVM_SW_ARB_ARB_REQ_CLR2 (1L<<6) +#define BNX2_NVM_SW_ARB_ARB_REQ_CLR3 (1L<<7) +#define BNX2_NVM_SW_ARB_ARB_ARB0 (1L<<8) +#define BNX2_NVM_SW_ARB_ARB_ARB1 (1L<<9) +#define BNX2_NVM_SW_ARB_ARB_ARB2 (1L<<10) +#define BNX2_NVM_SW_ARB_ARB_ARB3 (1L<<11) +#define BNX2_NVM_SW_ARB_REQ0 (1L<<12) +#define BNX2_NVM_SW_ARB_REQ1 (1L<<13) +#define BNX2_NVM_SW_ARB_REQ2 (1L<<14) +#define BNX2_NVM_SW_ARB_REQ3 (1L<<15) + +#define BNX2_NVM_ACCESS_ENABLE 0x00006424 +#define BNX2_NVM_ACCESS_ENABLE_EN (1L<<0) +#define BNX2_NVM_ACCESS_ENABLE_WR_EN (1L<<1) + +#define BNX2_NVM_WRITE1 0x00006428 +#define BNX2_NVM_WRITE1_WREN_CMD (0xffL<<0) +#define BNX2_NVM_WRITE1_WRDI_CMD (0xffL<<8) +#define BNX2_NVM_WRITE1_SR_DATA (0xffL<<16) + + + +/* + * dma_reg definition + * offset: 0xc00 + */ +#define BNX2_DMA_COMMAND 0x00000c00 +#define BNX2_DMA_COMMAND_ENABLE (1L<<0) + +#define BNX2_DMA_STATUS 0x00000c04 +#define BNX2_DMA_STATUS_PAR_ERROR_STATE (1L<<0) +#define BNX2_DMA_STATUS_READ_TRANSFERS_STAT (1L<<16) +#define BNX2_DMA_STATUS_READ_DELAY_PCI_CLKS_STAT (1L<<17) +#define BNX2_DMA_STATUS_BIG_READ_TRANSFERS_STAT (1L<<18) +#define BNX2_DMA_STATUS_BIG_READ_DELAY_PCI_CLKS_STAT (1L<<19) +#define BNX2_DMA_STATUS_BIG_READ_RETRY_AFTER_DATA_STAT (1L<<20) +#define BNX2_DMA_STATUS_WRITE_TRANSFERS_STAT (1L<<21) +#define BNX2_DMA_STATUS_WRITE_DELAY_PCI_CLKS_STAT (1L<<22) +#define BNX2_DMA_STATUS_BIG_WRITE_TRANSFERS_STAT (1L<<23) +#define BNX2_DMA_STATUS_BIG_WRITE_DELAY_PCI_CLKS_STAT (1L<<24) +#define BNX2_DMA_STATUS_BIG_WRITE_RETRY_AFTER_DATA_STAT (1L<<25) + +#define BNX2_DMA_CONFIG 0x00000c08 +#define BNX2_DMA_CONFIG_DATA_BYTE_SWAP (1L<<0) +#define BNX2_DMA_CONFIG_DATA_WORD_SWAP (1L<<1) +#define BNX2_DMA_CONFIG_CNTL_BYTE_SWAP (1L<<4) +#define BNX2_DMA_CONFIG_CNTL_WORD_SWAP (1L<<5) +#define BNX2_DMA_CONFIG_ONE_DMA (1L<<6) +#define BNX2_DMA_CONFIG_CNTL_TWO_DMA (1L<<7) +#define BNX2_DMA_CONFIG_CNTL_FPGA_MODE (1L<<8) +#define BNX2_DMA_CONFIG_CNTL_PING_PONG_DMA (1L<<10) +#define BNX2_DMA_CONFIG_CNTL_PCI_COMP_DLY (1L<<11) +#define BNX2_DMA_CONFIG_NO_RCHANS_IN_USE (0xfL<<12) +#define BNX2_DMA_CONFIG_NO_WCHANS_IN_USE (0xfL<<16) +#define BNX2_DMA_CONFIG_PCI_CLK_CMP_BITS (0x7L<<20) +#define BNX2_DMA_CONFIG_PCI_FAST_CLK_CMP (1L<<23) +#define BNX2_DMA_CONFIG_BIG_SIZE (0xfL<<24) +#define BNX2_DMA_CONFIG_BIG_SIZE_NONE (0x0L<<24) +#define BNX2_DMA_CONFIG_BIG_SIZE_64 (0x1L<<24) +#define BNX2_DMA_CONFIG_BIG_SIZE_128 (0x2L<<24) +#define BNX2_DMA_CONFIG_BIG_SIZE_256 (0x4L<<24) +#define BNX2_DMA_CONFIG_BIG_SIZE_512 (0x8L<<24) + +#define BNX2_DMA_BLACKOUT 0x00000c0c +#define BNX2_DMA_BLACKOUT_RD_RETRY_BLACKOUT (0xffL<<0) +#define BNX2_DMA_BLACKOUT_2ND_RD_RETRY_BLACKOUT (0xffL<<8) +#define BNX2_DMA_BLACKOUT_WR_RETRY_BLACKOUT (0xffL<<16) + +#define BNX2_DMA_RCHAN_STAT 0x00000c30 +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_0 (0x7L<<0) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_0 (1L<<3) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_1 (0x7L<<4) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_1 (1L<<7) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_2 (0x7L<<8) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_2 (1L<<11) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_3 (0x7L<<12) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_3 (1L<<15) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_4 (0x7L<<16) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_4 (1L<<19) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_5 (0x7L<<20) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_5 (1L<<23) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_6 (0x7L<<24) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_6 (1L<<27) +#define BNX2_DMA_RCHAN_STAT_COMP_CODE_7 (0x7L<<28) +#define BNX2_DMA_RCHAN_STAT_PAR_ERR_7 (1L<<31) + +#define BNX2_DMA_WCHAN_STAT 0x00000c34 +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_0 (0x7L<<0) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_0 (1L<<3) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_1 (0x7L<<4) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_1 (1L<<7) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_2 (0x7L<<8) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_2 (1L<<11) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_3 (0x7L<<12) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_3 (1L<<15) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_4 (0x7L<<16) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_4 (1L<<19) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_5 (0x7L<<20) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_5 (1L<<23) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_6 (0x7L<<24) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_6 (1L<<27) +#define BNX2_DMA_WCHAN_STAT_COMP_CODE_7 (0x7L<<28) +#define BNX2_DMA_WCHAN_STAT_PAR_ERR_7 (1L<<31) + +#define BNX2_DMA_RCHAN_ASSIGNMENT 0x00000c38 +#define BNX2_DMA_RCHAN_ASSIGNMENT_0 (0xfL<<0) +#define BNX2_DMA_RCHAN_ASSIGNMENT_1 (0xfL<<4) +#define BNX2_DMA_RCHAN_ASSIGNMENT_2 (0xfL<<8) +#define BNX2_DMA_RCHAN_ASSIGNMENT_3 (0xfL<<12) +#define BNX2_DMA_RCHAN_ASSIGNMENT_4 (0xfL<<16) +#define BNX2_DMA_RCHAN_ASSIGNMENT_5 (0xfL<<20) +#define BNX2_DMA_RCHAN_ASSIGNMENT_6 (0xfL<<24) +#define BNX2_DMA_RCHAN_ASSIGNMENT_7 (0xfL<<28) + +#define BNX2_DMA_WCHAN_ASSIGNMENT 0x00000c3c +#define BNX2_DMA_WCHAN_ASSIGNMENT_0 (0xfL<<0) +#define BNX2_DMA_WCHAN_ASSIGNMENT_1 (0xfL<<4) +#define BNX2_DMA_WCHAN_ASSIGNMENT_2 (0xfL<<8) +#define BNX2_DMA_WCHAN_ASSIGNMENT_3 (0xfL<<12) +#define BNX2_DMA_WCHAN_ASSIGNMENT_4 (0xfL<<16) +#define BNX2_DMA_WCHAN_ASSIGNMENT_5 (0xfL<<20) +#define BNX2_DMA_WCHAN_ASSIGNMENT_6 (0xfL<<24) +#define BNX2_DMA_WCHAN_ASSIGNMENT_7 (0xfL<<28) + +#define BNX2_DMA_RCHAN_STAT_00 0x00000c40 +#define BNX2_DMA_RCHAN_STAT_00_RCHAN_STA_HOST_ADDR_LOW (0xffffffffL<<0) + +#define BNX2_DMA_RCHAN_STAT_01 0x00000c44 +#define BNX2_DMA_RCHAN_STAT_01_RCHAN_STA_HOST_ADDR_HIGH (0xffffffffL<<0) + +#define BNX2_DMA_RCHAN_STAT_02 0x00000c48 +#define BNX2_DMA_RCHAN_STAT_02_LENGTH (0xffffL<<0) +#define BNX2_DMA_RCHAN_STAT_02_WORD_SWAP (1L<<16) +#define BNX2_DMA_RCHAN_STAT_02_BYTE_SWAP (1L<<17) +#define BNX2_DMA_RCHAN_STAT_02_PRIORITY_LVL (1L<<18) + +#define BNX2_DMA_RCHAN_STAT_10 0x00000c4c +#define BNX2_DMA_RCHAN_STAT_11 0x00000c50 +#define BNX2_DMA_RCHAN_STAT_12 0x00000c54 +#define BNX2_DMA_RCHAN_STAT_20 0x00000c58 +#define BNX2_DMA_RCHAN_STAT_21 0x00000c5c +#define BNX2_DMA_RCHAN_STAT_22 0x00000c60 +#define BNX2_DMA_RCHAN_STAT_30 0x00000c64 +#define BNX2_DMA_RCHAN_STAT_31 0x00000c68 +#define BNX2_DMA_RCHAN_STAT_32 0x00000c6c +#define BNX2_DMA_RCHAN_STAT_40 0x00000c70 +#define BNX2_DMA_RCHAN_STAT_41 0x00000c74 +#define BNX2_DMA_RCHAN_STAT_42 0x00000c78 +#define BNX2_DMA_RCHAN_STAT_50 0x00000c7c +#define BNX2_DMA_RCHAN_STAT_51 0x00000c80 +#define BNX2_DMA_RCHAN_STAT_52 0x00000c84 +#define BNX2_DMA_RCHAN_STAT_60 0x00000c88 +#define BNX2_DMA_RCHAN_STAT_61 0x00000c8c +#define BNX2_DMA_RCHAN_STAT_62 0x00000c90 +#define BNX2_DMA_RCHAN_STAT_70 0x00000c94 +#define BNX2_DMA_RCHAN_STAT_71 0x00000c98 +#define BNX2_DMA_RCHAN_STAT_72 0x00000c9c +#define BNX2_DMA_WCHAN_STAT_00 0x00000ca0 +#define BNX2_DMA_WCHAN_STAT_00_WCHAN_STA_HOST_ADDR_LOW (0xffffffffL<<0) + +#define BNX2_DMA_WCHAN_STAT_01 0x00000ca4 +#define BNX2_DMA_WCHAN_STAT_01_WCHAN_STA_HOST_ADDR_HIGH (0xffffffffL<<0) + +#define BNX2_DMA_WCHAN_STAT_02 0x00000ca8 +#define BNX2_DMA_WCHAN_STAT_02_LENGTH (0xffffL<<0) +#define BNX2_DMA_WCHAN_STAT_02_WORD_SWAP (1L<<16) +#define BNX2_DMA_WCHAN_STAT_02_BYTE_SWAP (1L<<17) +#define BNX2_DMA_WCHAN_STAT_02_PRIORITY_LVL (1L<<18) + +#define BNX2_DMA_WCHAN_STAT_10 0x00000cac +#define BNX2_DMA_WCHAN_STAT_11 0x00000cb0 +#define BNX2_DMA_WCHAN_STAT_12 0x00000cb4 +#define BNX2_DMA_WCHAN_STAT_20 0x00000cb8 +#define BNX2_DMA_WCHAN_STAT_21 0x00000cbc +#define BNX2_DMA_WCHAN_STAT_22 0x00000cc0 +#define BNX2_DMA_WCHAN_STAT_30 0x00000cc4 +#define BNX2_DMA_WCHAN_STAT_31 0x00000cc8 +#define BNX2_DMA_WCHAN_STAT_32 0x00000ccc +#define BNX2_DMA_WCHAN_STAT_40 0x00000cd0 +#define BNX2_DMA_WCHAN_STAT_41 0x00000cd4 +#define BNX2_DMA_WCHAN_STAT_42 0x00000cd8 +#define BNX2_DMA_WCHAN_STAT_50 0x00000cdc +#define BNX2_DMA_WCHAN_STAT_51 0x00000ce0 +#define BNX2_DMA_WCHAN_STAT_52 0x00000ce4 +#define BNX2_DMA_WCHAN_STAT_60 0x00000ce8 +#define BNX2_DMA_WCHAN_STAT_61 0x00000cec +#define BNX2_DMA_WCHAN_STAT_62 0x00000cf0 +#define BNX2_DMA_WCHAN_STAT_70 0x00000cf4 +#define BNX2_DMA_WCHAN_STAT_71 0x00000cf8 +#define BNX2_DMA_WCHAN_STAT_72 0x00000cfc +#define BNX2_DMA_ARB_STAT_00 0x00000d00 +#define BNX2_DMA_ARB_STAT_00_MASTER (0xffffL<<0) +#define BNX2_DMA_ARB_STAT_00_MASTER_ENC (0xffL<<16) +#define BNX2_DMA_ARB_STAT_00_CUR_BINMSTR (0xffL<<24) + +#define BNX2_DMA_ARB_STAT_01 0x00000d04 +#define BNX2_DMA_ARB_STAT_01_LPR_RPTR (0xfL<<0) +#define BNX2_DMA_ARB_STAT_01_LPR_WPTR (0xfL<<4) +#define BNX2_DMA_ARB_STAT_01_LPB_RPTR (0xfL<<8) +#define BNX2_DMA_ARB_STAT_01_LPB_WPTR (0xfL<<12) +#define BNX2_DMA_ARB_STAT_01_HPR_RPTR (0xfL<<16) +#define BNX2_DMA_ARB_STAT_01_HPR_WPTR (0xfL<<20) +#define BNX2_DMA_ARB_STAT_01_HPB_RPTR (0xfL<<24) +#define BNX2_DMA_ARB_STAT_01_HPB_WPTR (0xfL<<28) + +#define BNX2_DMA_FUSE_CTRL0_CMD 0x00000f00 +#define BNX2_DMA_FUSE_CTRL0_CMD_PWRUP_DONE (1L<<0) +#define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT_DONE (1L<<1) +#define BNX2_DMA_FUSE_CTRL0_CMD_SHIFT (1L<<2) +#define BNX2_DMA_FUSE_CTRL0_CMD_LOAD (1L<<3) +#define BNX2_DMA_FUSE_CTRL0_CMD_SEL (0xfL<<8) + +#define BNX2_DMA_FUSE_CTRL0_DATA 0x00000f04 +#define BNX2_DMA_FUSE_CTRL1_CMD 0x00000f08 +#define BNX2_DMA_FUSE_CTRL1_CMD_PWRUP_DONE (1L<<0) +#define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT_DONE (1L<<1) +#define BNX2_DMA_FUSE_CTRL1_CMD_SHIFT (1L<<2) +#define BNX2_DMA_FUSE_CTRL1_CMD_LOAD (1L<<3) +#define BNX2_DMA_FUSE_CTRL1_CMD_SEL (0xfL<<8) + +#define BNX2_DMA_FUSE_CTRL1_DATA 0x00000f0c +#define BNX2_DMA_FUSE_CTRL2_CMD 0x00000f10 +#define BNX2_DMA_FUSE_CTRL2_CMD_PWRUP_DONE (1L<<0) +#define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT_DONE (1L<<1) +#define BNX2_DMA_FUSE_CTRL2_CMD_SHIFT (1L<<2) +#define BNX2_DMA_FUSE_CTRL2_CMD_LOAD (1L<<3) +#define BNX2_DMA_FUSE_CTRL2_CMD_SEL (0xfL<<8) + +#define BNX2_DMA_FUSE_CTRL2_DATA 0x00000f14 + + +/* + * context_reg definition + * offset: 0x1000 + */ +#define BNX2_CTX_COMMAND 0x00001000 +#define BNX2_CTX_COMMAND_ENABLED (1L<<0) + +#define BNX2_CTX_STATUS 0x00001004 +#define BNX2_CTX_STATUS_LOCK_WAIT (1L<<0) +#define BNX2_CTX_STATUS_READ_STAT (1L<<16) +#define BNX2_CTX_STATUS_WRITE_STAT (1L<<17) +#define BNX2_CTX_STATUS_ACC_STALL_STAT (1L<<18) +#define BNX2_CTX_STATUS_LOCK_STALL_STAT (1L<<19) + +#define BNX2_CTX_VIRT_ADDR 0x00001008 +#define BNX2_CTX_VIRT_ADDR_VIRT_ADDR (0x7fffL<<6) + +#define BNX2_CTX_PAGE_TBL 0x0000100c +#define BNX2_CTX_PAGE_TBL_PAGE_TBL (0x3fffL<<6) + +#define BNX2_CTX_DATA_ADR 0x00001010 +#define BNX2_CTX_DATA_ADR_DATA_ADR (0x7ffffL<<2) + +#define BNX2_CTX_DATA 0x00001014 +#define BNX2_CTX_LOCK 0x00001018 +#define BNX2_CTX_LOCK_TYPE (0x7L<<0) +#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_VOID (0x0L<<0) +#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_COMPLETE (0x7L<<0) +#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_PROTOCOL (0x1L<<0) +#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TX (0x2L<<0) +#define BNX2_CTX_LOCK_TYPE_LOCK_TYPE_TIMER (0x4L<<0) +#define BNX2_CTX_LOCK_CID_VALUE (0x3fffL<<7) +#define BNX2_CTX_LOCK_GRANTED (1L<<26) +#define BNX2_CTX_LOCK_MODE (0x7L<<27) +#define BNX2_CTX_LOCK_MODE_UNLOCK (0x0L<<27) +#define BNX2_CTX_LOCK_MODE_IMMEDIATE (0x1L<<27) +#define BNX2_CTX_LOCK_MODE_SURE (0x2L<<27) +#define BNX2_CTX_LOCK_STATUS (1L<<30) +#define BNX2_CTX_LOCK_REQ (1L<<31) + +#define BNX2_CTX_ACCESS_STATUS 0x00001040 +#define BNX2_CTX_ACCESS_STATUS_MASTERENCODED (0xfL<<0) +#define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYSM (0x3L<<10) +#define BNX2_CTX_ACCESS_STATUS_PAGETABLEINITSM (0x3L<<12) +#define BNX2_CTX_ACCESS_STATUS_ACCESSMEMORYINITSM (0x3L<<14) +#define BNX2_CTX_ACCESS_STATUS_QUALIFIED_REQUEST (0x7ffL<<17) + +#define BNX2_CTX_DBG_LOCK_STATUS 0x00001044 +#define BNX2_CTX_DBG_LOCK_STATUS_SM (0x3ffL<<0) +#define BNX2_CTX_DBG_LOCK_STATUS_MATCH (0x3ffL<<22) + +#define BNX2_CTX_CHNL_LOCK_STATUS_0 0x00001080 +#define BNX2_CTX_CHNL_LOCK_STATUS_0_CID (0x3fffL<<0) +#define BNX2_CTX_CHNL_LOCK_STATUS_0_TYPE (0x3L<<14) +#define BNX2_CTX_CHNL_LOCK_STATUS_0_MODE (1L<<16) + +#define BNX2_CTX_CHNL_LOCK_STATUS_1 0x00001084 +#define BNX2_CTX_CHNL_LOCK_STATUS_2 0x00001088 +#define BNX2_CTX_CHNL_LOCK_STATUS_3 0x0000108c +#define BNX2_CTX_CHNL_LOCK_STATUS_4 0x00001090 +#define BNX2_CTX_CHNL_LOCK_STATUS_5 0x00001094 +#define BNX2_CTX_CHNL_LOCK_STATUS_6 0x00001098 +#define BNX2_CTX_CHNL_LOCK_STATUS_7 0x0000109c +#define BNX2_CTX_CHNL_LOCK_STATUS_8 0x000010a0 + + +/* + * emac_reg definition + * offset: 0x1400 + */ +#define BNX2_EMAC_MODE 0x00001400 +#define BNX2_EMAC_MODE_RESET (1L<<0) +#define BNX2_EMAC_MODE_HALF_DUPLEX (1L<<1) +#define BNX2_EMAC_MODE_PORT (0x3L<<2) +#define BNX2_EMAC_MODE_PORT_NONE (0L<<2) +#define BNX2_EMAC_MODE_PORT_MII (1L<<2) +#define BNX2_EMAC_MODE_PORT_GMII (2L<<2) +#define BNX2_EMAC_MODE_PORT_UNDEF (3L<<2) +#define BNX2_EMAC_MODE_MAC_LOOP (1L<<4) +#define BNX2_EMAC_MODE_TAGGED_MAC_CTL (1L<<7) +#define BNX2_EMAC_MODE_TX_BURST (1L<<8) +#define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA (1L<<9) +#define BNX2_EMAC_MODE_EXT_LINK_POL (1L<<10) +#define BNX2_EMAC_MODE_FORCE_LINK (1L<<11) +#define BNX2_EMAC_MODE_MPKT (1L<<18) +#define BNX2_EMAC_MODE_MPKT_RCVD (1L<<19) +#define BNX2_EMAC_MODE_ACPI_RCVD (1L<<20) + +#define BNX2_EMAC_STATUS 0x00001404 +#define BNX2_EMAC_STATUS_LINK (1L<<11) +#define BNX2_EMAC_STATUS_LINK_CHANGE (1L<<12) +#define BNX2_EMAC_STATUS_MI_COMPLETE (1L<<22) +#define BNX2_EMAC_STATUS_MI_INT (1L<<23) +#define BNX2_EMAC_STATUS_AP_ERROR (1L<<24) +#define BNX2_EMAC_STATUS_PARITY_ERROR_STATE (1L<<31) + +#define BNX2_EMAC_ATTENTION_ENA 0x00001408 +#define BNX2_EMAC_ATTENTION_ENA_LINK (1L<<11) +#define BNX2_EMAC_ATTENTION_ENA_MI_COMPLETE (1L<<22) +#define BNX2_EMAC_ATTENTION_ENA_MI_INT (1L<<23) +#define BNX2_EMAC_ATTENTION_ENA_AP_ERROR (1L<<24) + +#define BNX2_EMAC_LED 0x0000140c +#define BNX2_EMAC_LED_OVERRIDE (1L<<0) +#define BNX2_EMAC_LED_1000MB_OVERRIDE (1L<<1) +#define BNX2_EMAC_LED_100MB_OVERRIDE (1L<<2) +#define BNX2_EMAC_LED_10MB_OVERRIDE (1L<<3) +#define BNX2_EMAC_LED_TRAFFIC_OVERRIDE (1L<<4) +#define BNX2_EMAC_LED_BLNK_TRAFFIC (1L<<5) +#define BNX2_EMAC_LED_TRAFFIC (1L<<6) +#define BNX2_EMAC_LED_1000MB (1L<<7) +#define BNX2_EMAC_LED_100MB (1L<<8) +#define BNX2_EMAC_LED_10MB (1L<<9) +#define BNX2_EMAC_LED_TRAFFIC_STAT (1L<<10) +#define BNX2_EMAC_LED_BLNK_RATE (0xfffL<<19) +#define BNX2_EMAC_LED_BLNK_RATE_ENA (1L<<31) + +#define BNX2_EMAC_MAC_MATCH0 0x00001410 +#define BNX2_EMAC_MAC_MATCH1 0x00001414 +#define BNX2_EMAC_MAC_MATCH2 0x00001418 +#define BNX2_EMAC_MAC_MATCH3 0x0000141c +#define BNX2_EMAC_MAC_MATCH4 0x00001420 +#define BNX2_EMAC_MAC_MATCH5 0x00001424 +#define BNX2_EMAC_MAC_MATCH6 0x00001428 +#define BNX2_EMAC_MAC_MATCH7 0x0000142c +#define BNX2_EMAC_MAC_MATCH8 0x00001430 +#define BNX2_EMAC_MAC_MATCH9 0x00001434 +#define BNX2_EMAC_MAC_MATCH10 0x00001438 +#define BNX2_EMAC_MAC_MATCH11 0x0000143c +#define BNX2_EMAC_MAC_MATCH12 0x00001440 +#define BNX2_EMAC_MAC_MATCH13 0x00001444 +#define BNX2_EMAC_MAC_MATCH14 0x00001448 +#define BNX2_EMAC_MAC_MATCH15 0x0000144c +#define BNX2_EMAC_MAC_MATCH16 0x00001450 +#define BNX2_EMAC_MAC_MATCH17 0x00001454 +#define BNX2_EMAC_MAC_MATCH18 0x00001458 +#define BNX2_EMAC_MAC_MATCH19 0x0000145c +#define BNX2_EMAC_MAC_MATCH20 0x00001460 +#define BNX2_EMAC_MAC_MATCH21 0x00001464 +#define BNX2_EMAC_MAC_MATCH22 0x00001468 +#define BNX2_EMAC_MAC_MATCH23 0x0000146c +#define BNX2_EMAC_MAC_MATCH24 0x00001470 +#define BNX2_EMAC_MAC_MATCH25 0x00001474 +#define BNX2_EMAC_MAC_MATCH26 0x00001478 +#define BNX2_EMAC_MAC_MATCH27 0x0000147c +#define BNX2_EMAC_MAC_MATCH28 0x00001480 +#define BNX2_EMAC_MAC_MATCH29 0x00001484 +#define BNX2_EMAC_MAC_MATCH30 0x00001488 +#define BNX2_EMAC_MAC_MATCH31 0x0000148c +#define BNX2_EMAC_BACKOFF_SEED 0x00001498 +#define BNX2_EMAC_BACKOFF_SEED_EMAC_BACKOFF_SEED (0x3ffL<<0) + +#define BNX2_EMAC_RX_MTU_SIZE 0x0000149c +#define BNX2_EMAC_RX_MTU_SIZE_MTU_SIZE (0xffffL<<0) +#define BNX2_EMAC_RX_MTU_SIZE_JUMBO_ENA (1L<<31) + +#define BNX2_EMAC_SERDES_CNTL 0x000014a4 +#define BNX2_EMAC_SERDES_CNTL_RXR (0x7L<<0) +#define BNX2_EMAC_SERDES_CNTL_RXG (0x3L<<3) +#define BNX2_EMAC_SERDES_CNTL_RXCKSEL (1L<<6) +#define BNX2_EMAC_SERDES_CNTL_TXBIAS (0x7L<<7) +#define BNX2_EMAC_SERDES_CNTL_BGMAX (1L<<10) +#define BNX2_EMAC_SERDES_CNTL_BGMIN (1L<<11) +#define BNX2_EMAC_SERDES_CNTL_TXMODE (1L<<12) +#define BNX2_EMAC_SERDES_CNTL_TXEDGE (1L<<13) +#define BNX2_EMAC_SERDES_CNTL_SERDES_MODE (1L<<14) +#define BNX2_EMAC_SERDES_CNTL_PLLTEST (1L<<15) +#define BNX2_EMAC_SERDES_CNTL_CDET_EN (1L<<16) +#define BNX2_EMAC_SERDES_CNTL_TBI_LBK (1L<<17) +#define BNX2_EMAC_SERDES_CNTL_REMOTE_LBK (1L<<18) +#define BNX2_EMAC_SERDES_CNTL_REV_PHASE (1L<<19) +#define BNX2_EMAC_SERDES_CNTL_REGCTL12 (0x3L<<20) +#define BNX2_EMAC_SERDES_CNTL_REGCTL25 (0x3L<<22) + +#define BNX2_EMAC_SERDES_STATUS 0x000014a8 +#define BNX2_EMAC_SERDES_STATUS_RX_STAT (0xffL<<0) +#define BNX2_EMAC_SERDES_STATUS_COMMA_DET (1L<<8) + +#define BNX2_EMAC_MDIO_COMM 0x000014ac +#define BNX2_EMAC_MDIO_COMM_DATA (0xffffL<<0) +#define BNX2_EMAC_MDIO_COMM_REG_ADDR (0x1fL<<16) +#define BNX2_EMAC_MDIO_COMM_PHY_ADDR (0x1fL<<21) +#define BNX2_EMAC_MDIO_COMM_COMMAND (0x3L<<26) +#define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_0 (0L<<26) +#define BNX2_EMAC_MDIO_COMM_COMMAND_WRITE (1L<<26) +#define BNX2_EMAC_MDIO_COMM_COMMAND_READ (2L<<26) +#define BNX2_EMAC_MDIO_COMM_COMMAND_UNDEFINED_3 (3L<<26) +#define BNX2_EMAC_MDIO_COMM_FAIL (1L<<28) +#define BNX2_EMAC_MDIO_COMM_START_BUSY (1L<<29) +#define BNX2_EMAC_MDIO_COMM_DISEXT (1L<<30) + +#define BNX2_EMAC_MDIO_STATUS 0x000014b0 +#define BNX2_EMAC_MDIO_STATUS_LINK (1L<<0) +#define BNX2_EMAC_MDIO_STATUS_10MB (1L<<1) + +#define BNX2_EMAC_MDIO_MODE 0x000014b4 +#define BNX2_EMAC_MDIO_MODE_SHORT_PREAMBLE (1L<<1) +#define BNX2_EMAC_MDIO_MODE_AUTO_POLL (1L<<4) +#define BNX2_EMAC_MDIO_MODE_BIT_BANG (1L<<8) +#define BNX2_EMAC_MDIO_MODE_MDIO (1L<<9) +#define BNX2_EMAC_MDIO_MODE_MDIO_OE (1L<<10) +#define BNX2_EMAC_MDIO_MODE_MDC (1L<<11) +#define BNX2_EMAC_MDIO_MODE_MDINT (1L<<12) +#define BNX2_EMAC_MDIO_MODE_CLOCK_CNT (0x1fL<<16) + +#define BNX2_EMAC_MDIO_AUTO_STATUS 0x000014b8 +#define BNX2_EMAC_MDIO_AUTO_STATUS_AUTO_ERR (1L<<0) + +#define BNX2_EMAC_TX_MODE 0x000014bc +#define BNX2_EMAC_TX_MODE_RESET (1L<<0) +#define BNX2_EMAC_TX_MODE_EXT_PAUSE_EN (1L<<3) +#define BNX2_EMAC_TX_MODE_FLOW_EN (1L<<4) +#define BNX2_EMAC_TX_MODE_BIG_BACKOFF (1L<<5) +#define BNX2_EMAC_TX_MODE_LONG_PAUSE (1L<<6) +#define BNX2_EMAC_TX_MODE_LINK_AWARE (1L<<7) + +#define BNX2_EMAC_TX_STATUS 0x000014c0 +#define BNX2_EMAC_TX_STATUS_XOFFED (1L<<0) +#define BNX2_EMAC_TX_STATUS_XOFF_SENT (1L<<1) +#define BNX2_EMAC_TX_STATUS_XON_SENT (1L<<2) +#define BNX2_EMAC_TX_STATUS_LINK_UP (1L<<3) +#define BNX2_EMAC_TX_STATUS_UNDERRUN (1L<<4) + +#define BNX2_EMAC_TX_LENGTHS 0x000014c4 +#define BNX2_EMAC_TX_LENGTHS_SLOT (0xffL<<0) +#define BNX2_EMAC_TX_LENGTHS_IPG (0xfL<<8) +#define BNX2_EMAC_TX_LENGTHS_IPG_CRS (0x3L<<12) + +#define BNX2_EMAC_RX_MODE 0x000014c8 +#define BNX2_EMAC_RX_MODE_RESET (1L<<0) +#define BNX2_EMAC_RX_MODE_FLOW_EN (1L<<2) +#define BNX2_EMAC_RX_MODE_KEEP_MAC_CONTROL (1L<<3) +#define BNX2_EMAC_RX_MODE_KEEP_PAUSE (1L<<4) +#define BNX2_EMAC_RX_MODE_ACCEPT_OVERSIZE (1L<<5) +#define BNX2_EMAC_RX_MODE_ACCEPT_RUNTS (1L<<6) +#define BNX2_EMAC_RX_MODE_LLC_CHK (1L<<7) +#define BNX2_EMAC_RX_MODE_PROMISCUOUS (1L<<8) +#define BNX2_EMAC_RX_MODE_NO_CRC_CHK (1L<<9) +#define BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG (1L<<10) +#define BNX2_EMAC_RX_MODE_FILT_BROADCAST (1L<<11) +#define BNX2_EMAC_RX_MODE_SORT_MODE (1L<<12) + +#define BNX2_EMAC_RX_STATUS 0x000014cc +#define BNX2_EMAC_RX_STATUS_FFED (1L<<0) +#define BNX2_EMAC_RX_STATUS_FF_RECEIVED (1L<<1) +#define BNX2_EMAC_RX_STATUS_N_RECEIVED (1L<<2) + +#define BNX2_EMAC_MULTICAST_HASH0 0x000014d0 +#define BNX2_EMAC_MULTICAST_HASH1 0x000014d4 +#define BNX2_EMAC_MULTICAST_HASH2 0x000014d8 +#define BNX2_EMAC_MULTICAST_HASH3 0x000014dc +#define BNX2_EMAC_MULTICAST_HASH4 0x000014e0 +#define BNX2_EMAC_MULTICAST_HASH5 0x000014e4 +#define BNX2_EMAC_MULTICAST_HASH6 0x000014e8 +#define BNX2_EMAC_MULTICAST_HASH7 0x000014ec +#define BNX2_EMAC_RX_STAT_IFHCINOCTETS 0x00001500 +#define BNX2_EMAC_RX_STAT_IFHCINBADOCTETS 0x00001504 +#define BNX2_EMAC_RX_STAT_ETHERSTATSFRAGMENTS 0x00001508 +#define BNX2_EMAC_RX_STAT_IFHCINUCASTPKTS 0x0000150c +#define BNX2_EMAC_RX_STAT_IFHCINMULTICASTPKTS 0x00001510 +#define BNX2_EMAC_RX_STAT_IFHCINBROADCASTPKTS 0x00001514 +#define BNX2_EMAC_RX_STAT_DOT3STATSFCSERRORS 0x00001518 +#define BNX2_EMAC_RX_STAT_DOT3STATSALIGNMENTERRORS 0x0000151c +#define BNX2_EMAC_RX_STAT_DOT3STATSCARRIERSENSEERRORS 0x00001520 +#define BNX2_EMAC_RX_STAT_XONPAUSEFRAMESRECEIVED 0x00001524 +#define BNX2_EMAC_RX_STAT_XOFFPAUSEFRAMESRECEIVED 0x00001528 +#define BNX2_EMAC_RX_STAT_MACCONTROLFRAMESRECEIVED 0x0000152c +#define BNX2_EMAC_RX_STAT_XOFFSTATEENTERED 0x00001530 +#define BNX2_EMAC_RX_STAT_DOT3STATSFRAMESTOOLONG 0x00001534 +#define BNX2_EMAC_RX_STAT_ETHERSTATSJABBERS 0x00001538 +#define BNX2_EMAC_RX_STAT_ETHERSTATSUNDERSIZEPKTS 0x0000153c +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS64OCTETS 0x00001540 +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS 0x00001544 +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS 0x00001548 +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS 0x0000154c +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001550 +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x00001554 +#define BNX2_EMAC_RX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001558 +#define BNX2_EMAC_RXMAC_DEBUG0 0x0000155c +#define BNX2_EMAC_RXMAC_DEBUG1 0x00001560 +#define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_NE_BYTE_COUNT (1L<<0) +#define BNX2_EMAC_RXMAC_DEBUG1_LENGTH_OUT_RANGE (1L<<1) +#define BNX2_EMAC_RXMAC_DEBUG1_BAD_CRC (1L<<2) +#define BNX2_EMAC_RXMAC_DEBUG1_RX_ERROR (1L<<3) +#define BNX2_EMAC_RXMAC_DEBUG1_ALIGN_ERROR (1L<<4) +#define BNX2_EMAC_RXMAC_DEBUG1_LAST_DATA (1L<<5) +#define BNX2_EMAC_RXMAC_DEBUG1_ODD_BYTE_START (1L<<6) +#define BNX2_EMAC_RXMAC_DEBUG1_BYTE_COUNT (0xffffL<<7) +#define BNX2_EMAC_RXMAC_DEBUG1_SLOT_TIME (0xffL<<23) + +#define BNX2_EMAC_RXMAC_DEBUG2 0x00001564 +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE (0x7L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_IDLE (0x0L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SFD (0x1L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DATA (0x2L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SKEEP (0x3L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_EXT (0x4L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_DROP (0x5L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_SDROP (0x6L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_SM_STATE_FC (0x7L<<0) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE (0xfL<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_IDLE (0x0L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA0 (0x1L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA1 (0x2L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA2 (0x3L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_DATA3 (0x4L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_ABORT (0x5L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_WAIT (0x6L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_STATUS (0x7L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_IDI_STATE_LAST (0x8L<<3) +#define BNX2_EMAC_RXMAC_DEBUG2_BYTE_IN (0xffL<<7) +#define BNX2_EMAC_RXMAC_DEBUG2_FALSEC (1L<<15) +#define BNX2_EMAC_RXMAC_DEBUG2_TAGGED (1L<<16) +#define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE (1L<<18) +#define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_IDLE (0L<<18) +#define BNX2_EMAC_RXMAC_DEBUG2_PAUSE_STATE_PAUSED (1L<<18) +#define BNX2_EMAC_RXMAC_DEBUG2_SE_COUNTER (0xfL<<19) +#define BNX2_EMAC_RXMAC_DEBUG2_QUANTA (0x1fL<<23) + +#define BNX2_EMAC_RXMAC_DEBUG3 0x00001568 +#define BNX2_EMAC_RXMAC_DEBUG3_PAUSE_CTR (0xffffL<<0) +#define BNX2_EMAC_RXMAC_DEBUG3_TMP_PAUSE_CTR (0xffffL<<16) + +#define BNX2_EMAC_RXMAC_DEBUG4 0x0000156c +#define BNX2_EMAC_RXMAC_DEBUG4_TYPE_FIELD (0xffffL<<0) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE (0x3fL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_IDLE (0x0L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC2 (0x1L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UMAC3 (0x2L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UNI (0x3L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC2 (0x7L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MMAC3 (0x5L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA1 (0x6L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA2 (0x7L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PSA3 (0x8L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC2 (0x9L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC3 (0xaL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT1 (0xeL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MWAIT2 (0xfL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MCHECK (0x10L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MC (0x11L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC2 (0x12L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC3 (0x13L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA1 (0x14L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA2 (0x15L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BSA3 (0x16L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BTYPE (0x17L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_BC (0x18L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PTYPE (0x19L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_CMD (0x1aL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MAC (0x1bL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_LATCH (0x1cL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XOFF (0x1dL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_XON (0x1eL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_PAUSED (0x1fL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_NPAUSED (0x20L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TTYPE (0x21L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_TVAL (0x22L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA1 (0x23L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA2 (0x24L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_USA3 (0x25L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTYPE (0x26L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTTYPE (0x27L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_UTVAL (0x28L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_MTYPE (0x29L<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_FILT_STATE_DROP (0x2aL<<16) +#define BNX2_EMAC_RXMAC_DEBUG4_DROP_PKT (1L<<22) +#define BNX2_EMAC_RXMAC_DEBUG4_SLOT_FILLED (1L<<23) +#define BNX2_EMAC_RXMAC_DEBUG4_FALSE_CARRIER (1L<<24) +#define BNX2_EMAC_RXMAC_DEBUG4_LAST_DATA (1L<<25) +#define BNX2_EMAC_RXMAC_DEBUG4_sfd_FOUND (1L<<26) +#define BNX2_EMAC_RXMAC_DEBUG4_ADVANCE (1L<<27) +#define BNX2_EMAC_RXMAC_DEBUG4_START (1L<<28) + +#define BNX2_EMAC_RXMAC_DEBUG5 0x00001570 +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM (0x7L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_IDLE (0L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_EOF (1L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_WAIT_STAT (2L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4FCRC (3L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4RDE (4L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_SET_EOF4ALL (5L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_PS_IDISM_1WD_WAIT_STAT (6L<<0) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1 (0x7L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_VDW (0x0L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_STAT (0x1L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_AEOF (0x2L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_NEOF (0x3L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SOF (0x4L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SAEOF (0x6L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF1_SNEOF (0x7L<<4) +#define BNX2_EMAC_RXMAC_DEBUG5_EOF_DETECTED (1L<<7) +#define BNX2_EMAC_RXMAC_DEBUG5_CCODE_BUF0 (0x7L<<8) +#define BNX2_EMAC_RXMAC_DEBUG5_RPM_IDI_FIFO_FULL (1L<<11) +#define BNX2_EMAC_RXMAC_DEBUG5_LOAD_CCODE (1L<<12) +#define BNX2_EMAC_RXMAC_DEBUG5_LOAD_DATA (1L<<13) +#define BNX2_EMAC_RXMAC_DEBUG5_LOAD_STAT (1L<<14) +#define BNX2_EMAC_RXMAC_DEBUG5_CLR_STAT (1L<<15) +#define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_CCODE (0x3L<<16) +#define BNX2_EMAC_RXMAC_DEBUG5_IDI_RPM_ACCEPT (1L<<19) +#define BNX2_EMAC_RXMAC_DEBUG5_FMLEN (0xfffL<<20) + +#define BNX2_EMAC_RX_STAT_AC0 0x00001580 +#define BNX2_EMAC_RX_STAT_AC1 0x00001584 +#define BNX2_EMAC_RX_STAT_AC2 0x00001588 +#define BNX2_EMAC_RX_STAT_AC3 0x0000158c +#define BNX2_EMAC_RX_STAT_AC4 0x00001590 +#define BNX2_EMAC_RX_STAT_AC5 0x00001594 +#define BNX2_EMAC_RX_STAT_AC6 0x00001598 +#define BNX2_EMAC_RX_STAT_AC7 0x0000159c +#define BNX2_EMAC_RX_STAT_AC8 0x000015a0 +#define BNX2_EMAC_RX_STAT_AC9 0x000015a4 +#define BNX2_EMAC_RX_STAT_AC10 0x000015a8 +#define BNX2_EMAC_RX_STAT_AC11 0x000015ac +#define BNX2_EMAC_RX_STAT_AC12 0x000015b0 +#define BNX2_EMAC_RX_STAT_AC13 0x000015b4 +#define BNX2_EMAC_RX_STAT_AC14 0x000015b8 +#define BNX2_EMAC_RX_STAT_AC15 0x000015bc +#define BNX2_EMAC_RX_STAT_AC16 0x000015c0 +#define BNX2_EMAC_RX_STAT_AC17 0x000015c4 +#define BNX2_EMAC_RX_STAT_AC18 0x000015c8 +#define BNX2_EMAC_RX_STAT_AC19 0x000015cc +#define BNX2_EMAC_RX_STAT_AC20 0x000015d0 +#define BNX2_EMAC_RX_STAT_AC21 0x000015d4 +#define BNX2_EMAC_RX_STAT_AC22 0x000015d8 +#define BNX2_EMAC_RXMAC_SUC_DBG_OVERRUNVEC 0x000015dc +#define BNX2_EMAC_TX_STAT_IFHCOUTOCTETS 0x00001600 +#define BNX2_EMAC_TX_STAT_IFHCOUTBADOCTETS 0x00001604 +#define BNX2_EMAC_TX_STAT_ETHERSTATSCOLLISIONS 0x00001608 +#define BNX2_EMAC_TX_STAT_OUTXONSENT 0x0000160c +#define BNX2_EMAC_TX_STAT_OUTXOFFSENT 0x00001610 +#define BNX2_EMAC_TX_STAT_FLOWCONTROLDONE 0x00001614 +#define BNX2_EMAC_TX_STAT_DOT3STATSSINGLECOLLISIONFRAMES 0x00001618 +#define BNX2_EMAC_TX_STAT_DOT3STATSMULTIPLECOLLISIONFRAMES 0x0000161c +#define BNX2_EMAC_TX_STAT_DOT3STATSDEFERREDTRANSMISSIONS 0x00001620 +#define BNX2_EMAC_TX_STAT_DOT3STATSEXCESSIVECOLLISIONS 0x00001624 +#define BNX2_EMAC_TX_STAT_DOT3STATSLATECOLLISIONS 0x00001628 +#define BNX2_EMAC_TX_STAT_IFHCOUTUCASTPKTS 0x0000162c +#define BNX2_EMAC_TX_STAT_IFHCOUTMULTICASTPKTS 0x00001630 +#define BNX2_EMAC_TX_STAT_IFHCOUTBROADCASTPKTS 0x00001634 +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS64OCTETS 0x00001638 +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS65OCTETSTO127OCTETS 0x0000163c +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS128OCTETSTO255OCTETS 0x00001640 +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS256OCTETSTO511OCTETS 0x00001644 +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS512OCTETSTO1023OCTETS 0x00001648 +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1024OCTETSTO1522OCTETS 0x0000164c +#define BNX2_EMAC_TX_STAT_ETHERSTATSPKTS1523OCTETSTO9022OCTETS 0x00001650 +#define BNX2_EMAC_TX_STAT_DOT3STATSINTERNALMACTRANSMITERRORS 0x00001654 +#define BNX2_EMAC_TXMAC_DEBUG0 0x00001658 +#define BNX2_EMAC_TXMAC_DEBUG1 0x0000165c +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE (0xfL<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_IDLE (0x0L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_START0 (0x1L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA0 (0x4L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA1 (0x5L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA2 (0x6L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_DATA3 (0x7L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT0 (0x8L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_ODI_STATE_WAIT1 (0x9L<<0) +#define BNX2_EMAC_TXMAC_DEBUG1_CRS_ENABLE (1L<<4) +#define BNX2_EMAC_TXMAC_DEBUG1_BAD_CRC (1L<<5) +#define BNX2_EMAC_TXMAC_DEBUG1_SE_COUNTER (0xfL<<6) +#define BNX2_EMAC_TXMAC_DEBUG1_SEND_PAUSE (1L<<10) +#define BNX2_EMAC_TXMAC_DEBUG1_LATE_COLLISION (1L<<11) +#define BNX2_EMAC_TXMAC_DEBUG1_MAX_DEFER (1L<<12) +#define BNX2_EMAC_TXMAC_DEBUG1_DEFERRED (1L<<13) +#define BNX2_EMAC_TXMAC_DEBUG1_ONE_BYTE (1L<<14) +#define BNX2_EMAC_TXMAC_DEBUG1_IPG_TIME (0xfL<<15) +#define BNX2_EMAC_TXMAC_DEBUG1_SLOT_TIME (0xffL<<19) + +#define BNX2_EMAC_TXMAC_DEBUG2 0x00001660 +#define BNX2_EMAC_TXMAC_DEBUG2_BACK_OFF (0x3ffL<<0) +#define BNX2_EMAC_TXMAC_DEBUG2_BYTE_COUNT (0xffffL<<10) +#define BNX2_EMAC_TXMAC_DEBUG2_COL_COUNT (0x1fL<<26) +#define BNX2_EMAC_TXMAC_DEBUG2_COL_BIT (1L<<31) + +#define BNX2_EMAC_TXMAC_DEBUG3 0x00001664 +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE (0xfL<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_IDLE (0x0L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE1 (0x1L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_PRE2 (0x2L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SFD (0x3L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_DATA (0x4L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC1 (0x5L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_CRC2 (0x6L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EXT (0x7L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATB (0x8L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_STATG (0x9L<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_JAM (0xaL<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_EJAM (0xbL<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BJAM (0xcL<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_SWAIT (0xdL<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_SM_STATE_BACKOFF (0xeL<<0) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE (0x7L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_IDLE (0x0L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_WAIT (0x1L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_UNI (0x2L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_MC (0x3L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC2 (0x4L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC3 (0x5L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_FILT_STATE_BC (0x6L<<4) +#define BNX2_EMAC_TXMAC_DEBUG3_CRS_DONE (1L<<7) +#define BNX2_EMAC_TXMAC_DEBUG3_XOFF (1L<<8) +#define BNX2_EMAC_TXMAC_DEBUG3_SE_COUNTER (0xfL<<9) +#define BNX2_EMAC_TXMAC_DEBUG3_QUANTA_COUNTER (0x1fL<<13) + +#define BNX2_EMAC_TXMAC_DEBUG4 0x00001668 +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_COUNTER (0xffffL<<0) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE (0xfL<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_IDLE (0x0L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA1 (0x2L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA2 (0x3L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_MCA3 (0x6L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC1 (0x7L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC2 (0x5L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_SRC3 (0x4L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TYPE (0xcL<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CMD (0xeL<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_TIME (0xaL<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC1 (0x8L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_CRC2 (0x9L<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_PAUSE_STATE_WAIT (0xdL<<16) +#define BNX2_EMAC_TXMAC_DEBUG4_STATS0_VALID (1L<<20) +#define BNX2_EMAC_TXMAC_DEBUG4_APPEND_CRC (1L<<21) +#define BNX2_EMAC_TXMAC_DEBUG4_SLOT_FILLED (1L<<22) +#define BNX2_EMAC_TXMAC_DEBUG4_MAX_DEFER (1L<<23) +#define BNX2_EMAC_TXMAC_DEBUG4_SEND_EXTEND (1L<<24) +#define BNX2_EMAC_TXMAC_DEBUG4_SEND_PADDING (1L<<25) +#define BNX2_EMAC_TXMAC_DEBUG4_EOF_LOC (1L<<26) +#define BNX2_EMAC_TXMAC_DEBUG4_COLLIDING (1L<<27) +#define BNX2_EMAC_TXMAC_DEBUG4_COL_IN (1L<<28) +#define BNX2_EMAC_TXMAC_DEBUG4_BURSTING (1L<<29) +#define BNX2_EMAC_TXMAC_DEBUG4_ADVANCE (1L<<30) +#define BNX2_EMAC_TXMAC_DEBUG4_GO (1L<<31) + +#define BNX2_EMAC_TX_STAT_AC0 0x00001680 +#define BNX2_EMAC_TX_STAT_AC1 0x00001684 +#define BNX2_EMAC_TX_STAT_AC2 0x00001688 +#define BNX2_EMAC_TX_STAT_AC3 0x0000168c +#define BNX2_EMAC_TX_STAT_AC4 0x00001690 +#define BNX2_EMAC_TX_STAT_AC5 0x00001694 +#define BNX2_EMAC_TX_STAT_AC6 0x00001698 +#define BNX2_EMAC_TX_STAT_AC7 0x0000169c +#define BNX2_EMAC_TX_STAT_AC8 0x000016a0 +#define BNX2_EMAC_TX_STAT_AC9 0x000016a4 +#define BNX2_EMAC_TX_STAT_AC10 0x000016a8 +#define BNX2_EMAC_TX_STAT_AC11 0x000016ac +#define BNX2_EMAC_TX_STAT_AC12 0x000016b0 +#define BNX2_EMAC_TX_STAT_AC13 0x000016b4 +#define BNX2_EMAC_TX_STAT_AC14 0x000016b8 +#define BNX2_EMAC_TX_STAT_AC15 0x000016bc +#define BNX2_EMAC_TX_STAT_AC16 0x000016c0 +#define BNX2_EMAC_TX_STAT_AC17 0x000016c4 +#define BNX2_EMAC_TX_STAT_AC18 0x000016c8 +#define BNX2_EMAC_TX_STAT_AC19 0x000016cc +#define BNX2_EMAC_TX_STAT_AC20 0x000016d0 +#define BNX2_EMAC_TX_STAT_AC21 0x000016d4 +#define BNX2_EMAC_TXMAC_SUC_DBG_OVERRUNVEC 0x000016d8 + + +/* + * rpm_reg definition + * offset: 0x1800 + */ +#define BNX2_RPM_COMMAND 0x00001800 +#define BNX2_RPM_COMMAND_ENABLED (1L<<0) +#define BNX2_RPM_COMMAND_OVERRUN_ABORT (1L<<4) + +#define BNX2_RPM_STATUS 0x00001804 +#define BNX2_RPM_STATUS_MBUF_WAIT (1L<<0) +#define BNX2_RPM_STATUS_FREE_WAIT (1L<<1) + +#define BNX2_RPM_CONFIG 0x00001808 +#define BNX2_RPM_CONFIG_NO_PSD_HDR_CKSUM (1L<<0) +#define BNX2_RPM_CONFIG_ACPI_ENA (1L<<1) +#define BNX2_RPM_CONFIG_ACPI_KEEP (1L<<2) +#define BNX2_RPM_CONFIG_MP_KEEP (1L<<3) +#define BNX2_RPM_CONFIG_SORT_VECT_VAL (0xfL<<4) +#define BNX2_RPM_CONFIG_IGNORE_VLAN (1L<<31) + +#define BNX2_RPM_VLAN_MATCH0 0x00001810 +#define BNX2_RPM_VLAN_MATCH0_RPM_VLAN_MTCH0_VALUE (0xfffL<<0) + +#define BNX2_RPM_VLAN_MATCH1 0x00001814 +#define BNX2_RPM_VLAN_MATCH1_RPM_VLAN_MTCH1_VALUE (0xfffL<<0) + +#define BNX2_RPM_VLAN_MATCH2 0x00001818 +#define BNX2_RPM_VLAN_MATCH2_RPM_VLAN_MTCH2_VALUE (0xfffL<<0) + +#define BNX2_RPM_VLAN_MATCH3 0x0000181c +#define BNX2_RPM_VLAN_MATCH3_RPM_VLAN_MTCH3_VALUE (0xfffL<<0) + +#define BNX2_RPM_SORT_USER0 0x00001820 +#define BNX2_RPM_SORT_USER0_PM_EN (0xffffL<<0) +#define BNX2_RPM_SORT_USER0_BC_EN (1L<<16) +#define BNX2_RPM_SORT_USER0_MC_EN (1L<<17) +#define BNX2_RPM_SORT_USER0_MC_HSH_EN (1L<<18) +#define BNX2_RPM_SORT_USER0_PROM_EN (1L<<19) +#define BNX2_RPM_SORT_USER0_VLAN_EN (0xfL<<20) +#define BNX2_RPM_SORT_USER0_PROM_VLAN (1L<<24) +#define BNX2_RPM_SORT_USER0_ENA (1L<<31) + +#define BNX2_RPM_SORT_USER1 0x00001824 +#define BNX2_RPM_SORT_USER1_PM_EN (0xffffL<<0) +#define BNX2_RPM_SORT_USER1_BC_EN (1L<<16) +#define BNX2_RPM_SORT_USER1_MC_EN (1L<<17) +#define BNX2_RPM_SORT_USER1_MC_HSH_EN (1L<<18) +#define BNX2_RPM_SORT_USER1_PROM_EN (1L<<19) +#define BNX2_RPM_SORT_USER1_VLAN_EN (0xfL<<20) +#define BNX2_RPM_SORT_USER1_PROM_VLAN (1L<<24) +#define BNX2_RPM_SORT_USER1_ENA (1L<<31) + +#define BNX2_RPM_SORT_USER2 0x00001828 +#define BNX2_RPM_SORT_USER2_PM_EN (0xffffL<<0) +#define BNX2_RPM_SORT_USER2_BC_EN (1L<<16) +#define BNX2_RPM_SORT_USER2_MC_EN (1L<<17) +#define BNX2_RPM_SORT_USER2_MC_HSH_EN (1L<<18) +#define BNX2_RPM_SORT_USER2_PROM_EN (1L<<19) +#define BNX2_RPM_SORT_USER2_VLAN_EN (0xfL<<20) +#define BNX2_RPM_SORT_USER2_PROM_VLAN (1L<<24) +#define BNX2_RPM_SORT_USER2_ENA (1L<<31) + +#define BNX2_RPM_SORT_USER3 0x0000182c +#define BNX2_RPM_SORT_USER3_PM_EN (0xffffL<<0) +#define BNX2_RPM_SORT_USER3_BC_EN (1L<<16) +#define BNX2_RPM_SORT_USER3_MC_EN (1L<<17) +#define BNX2_RPM_SORT_USER3_MC_HSH_EN (1L<<18) +#define BNX2_RPM_SORT_USER3_PROM_EN (1L<<19) +#define BNX2_RPM_SORT_USER3_VLAN_EN (0xfL<<20) +#define BNX2_RPM_SORT_USER3_PROM_VLAN (1L<<24) +#define BNX2_RPM_SORT_USER3_ENA (1L<<31) + +#define BNX2_RPM_STAT_L2_FILTER_DISCARDS 0x00001840 +#define BNX2_RPM_STAT_RULE_CHECKER_DISCARDS 0x00001844 +#define BNX2_RPM_STAT_IFINFTQDISCARDS 0x00001848 +#define BNX2_RPM_STAT_IFINMBUFDISCARD 0x0000184c +#define BNX2_RPM_STAT_RULE_CHECKER_P4_HIT 0x00001850 +#define BNX2_RPM_STAT_AC0 0x00001880 +#define BNX2_RPM_STAT_AC1 0x00001884 +#define BNX2_RPM_STAT_AC2 0x00001888 +#define BNX2_RPM_STAT_AC3 0x0000188c +#define BNX2_RPM_STAT_AC4 0x00001890 +#define BNX2_RPM_RC_CNTL_0 0x00001900 +#define BNX2_RPM_RC_CNTL_0_OFFSET (0xffL<<0) +#define BNX2_RPM_RC_CNTL_0_CLASS (0x7L<<8) +#define BNX2_RPM_RC_CNTL_0_PRIORITY (1L<<11) +#define BNX2_RPM_RC_CNTL_0_P4 (1L<<12) +#define BNX2_RPM_RC_CNTL_0_HDR_TYPE (0x7L<<13) +#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_START (0L<<13) +#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_IP (1L<<13) +#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_TCP (2L<<13) +#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_UDP (3L<<13) +#define BNX2_RPM_RC_CNTL_0_HDR_TYPE_DATA (4L<<13) +#define BNX2_RPM_RC_CNTL_0_COMP (0x3L<<16) +#define BNX2_RPM_RC_CNTL_0_COMP_EQUAL (0L<<16) +#define BNX2_RPM_RC_CNTL_0_COMP_NEQUAL (1L<<16) +#define BNX2_RPM_RC_CNTL_0_COMP_GREATER (2L<<16) +#define BNX2_RPM_RC_CNTL_0_COMP_LESS (3L<<16) +#define BNX2_RPM_RC_CNTL_0_SBIT (1L<<19) +#define BNX2_RPM_RC_CNTL_0_CMDSEL (0xfL<<20) +#define BNX2_RPM_RC_CNTL_0_MAP (1L<<24) +#define BNX2_RPM_RC_CNTL_0_DISCARD (1L<<25) +#define BNX2_RPM_RC_CNTL_0_MASK (1L<<26) +#define BNX2_RPM_RC_CNTL_0_P1 (1L<<27) +#define BNX2_RPM_RC_CNTL_0_P2 (1L<<28) +#define BNX2_RPM_RC_CNTL_0_P3 (1L<<29) +#define BNX2_RPM_RC_CNTL_0_NBIT (1L<<30) + +#define BNX2_RPM_RC_VALUE_MASK_0 0x00001904 +#define BNX2_RPM_RC_VALUE_MASK_0_VALUE (0xffffL<<0) +#define BNX2_RPM_RC_VALUE_MASK_0_MASK (0xffffL<<16) + +#define BNX2_RPM_RC_CNTL_1 0x00001908 +#define BNX2_RPM_RC_CNTL_1_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_1_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_1 0x0000190c +#define BNX2_RPM_RC_CNTL_2 0x00001910 +#define BNX2_RPM_RC_CNTL_2_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_2_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_2 0x00001914 +#define BNX2_RPM_RC_CNTL_3 0x00001918 +#define BNX2_RPM_RC_CNTL_3_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_3_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_3 0x0000191c +#define BNX2_RPM_RC_CNTL_4 0x00001920 +#define BNX2_RPM_RC_CNTL_4_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_4_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_4 0x00001924 +#define BNX2_RPM_RC_CNTL_5 0x00001928 +#define BNX2_RPM_RC_CNTL_5_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_5_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_5 0x0000192c +#define BNX2_RPM_RC_CNTL_6 0x00001930 +#define BNX2_RPM_RC_CNTL_6_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_6_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_6 0x00001934 +#define BNX2_RPM_RC_CNTL_7 0x00001938 +#define BNX2_RPM_RC_CNTL_7_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_7_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_7 0x0000193c +#define BNX2_RPM_RC_CNTL_8 0x00001940 +#define BNX2_RPM_RC_CNTL_8_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_8_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_8 0x00001944 +#define BNX2_RPM_RC_CNTL_9 0x00001948 +#define BNX2_RPM_RC_CNTL_9_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_9_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_9 0x0000194c +#define BNX2_RPM_RC_CNTL_10 0x00001950 +#define BNX2_RPM_RC_CNTL_10_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_10_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_10 0x00001954 +#define BNX2_RPM_RC_CNTL_11 0x00001958 +#define BNX2_RPM_RC_CNTL_11_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_11_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_11 0x0000195c +#define BNX2_RPM_RC_CNTL_12 0x00001960 +#define BNX2_RPM_RC_CNTL_12_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_12_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_12 0x00001964 +#define BNX2_RPM_RC_CNTL_13 0x00001968 +#define BNX2_RPM_RC_CNTL_13_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_13_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_13 0x0000196c +#define BNX2_RPM_RC_CNTL_14 0x00001970 +#define BNX2_RPM_RC_CNTL_14_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_14_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_14 0x00001974 +#define BNX2_RPM_RC_CNTL_15 0x00001978 +#define BNX2_RPM_RC_CNTL_15_A (0x3ffffL<<0) +#define BNX2_RPM_RC_CNTL_15_B (0xfffL<<19) + +#define BNX2_RPM_RC_VALUE_MASK_15 0x0000197c +#define BNX2_RPM_RC_CONFIG 0x00001980 +#define BNX2_RPM_RC_CONFIG_RULE_ENABLE (0xffffL<<0) +#define BNX2_RPM_RC_CONFIG_DEF_CLASS (0x7L<<24) + +#define BNX2_RPM_DEBUG0 0x00001984 +#define BNX2_RPM_DEBUG0_FM_BCNT (0xffffL<<0) +#define BNX2_RPM_DEBUG0_T_DATA_OFST_VLD (1L<<16) +#define BNX2_RPM_DEBUG0_T_UDP_OFST_VLD (1L<<17) +#define BNX2_RPM_DEBUG0_T_TCP_OFST_VLD (1L<<18) +#define BNX2_RPM_DEBUG0_T_IP_OFST_VLD (1L<<19) +#define BNX2_RPM_DEBUG0_IP_MORE_FRGMT (1L<<20) +#define BNX2_RPM_DEBUG0_T_IP_NO_TCP_UDP_HDR (1L<<21) +#define BNX2_RPM_DEBUG0_LLC_SNAP (1L<<22) +#define BNX2_RPM_DEBUG0_FM_STARTED (1L<<23) +#define BNX2_RPM_DEBUG0_DONE (1L<<24) +#define BNX2_RPM_DEBUG0_WAIT_4_DONE (1L<<25) +#define BNX2_RPM_DEBUG0_USE_TPBUF_CKSUM (1L<<26) +#define BNX2_RPM_DEBUG0_RX_NO_PSD_HDR_CKSUM (1L<<27) +#define BNX2_RPM_DEBUG0_IGNORE_VLAN (1L<<28) +#define BNX2_RPM_DEBUG0_RP_ENA_ACTIVE (1L<<31) + +#define BNX2_RPM_DEBUG1 0x00001988 +#define BNX2_RPM_DEBUG1_FSM_CUR_ST (0xffffL<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_IDLE (0L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_ALL (1L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IPLLC (2L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B6_IP (4L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ETYPE_B2_IP (8L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP_START (16L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_IP (32L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_TCP (64L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_UDP (128L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_AH (256L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP (512L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ESP_PAYLOAD (1024L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_DATA (2048L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRY (0x2000L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_ADD_CARRYOUT (0x4000L<<0) +#define BNX2_RPM_DEBUG1_FSM_CUR_ST_LATCH_RESULT (0x8000L<<0) +#define BNX2_RPM_DEBUG1_HDR_BCNT (0x7ffL<<16) +#define BNX2_RPM_DEBUG1_UNKNOWN_ETYPE_D (1L<<28) +#define BNX2_RPM_DEBUG1_VLAN_REMOVED_D2 (1L<<29) +#define BNX2_RPM_DEBUG1_VLAN_REMOVED_D1 (1L<<30) +#define BNX2_RPM_DEBUG1_EOF_0XTRA_WD (1L<<31) + +#define BNX2_RPM_DEBUG2 0x0000198c +#define BNX2_RPM_DEBUG2_CMD_HIT_VEC (0xffffL<<0) +#define BNX2_RPM_DEBUG2_IP_BCNT (0xffL<<16) +#define BNX2_RPM_DEBUG2_THIS_CMD_M4 (1L<<24) +#define BNX2_RPM_DEBUG2_THIS_CMD_M3 (1L<<25) +#define BNX2_RPM_DEBUG2_THIS_CMD_M2 (1L<<26) +#define BNX2_RPM_DEBUG2_THIS_CMD_M1 (1L<<27) +#define BNX2_RPM_DEBUG2_IPIPE_EMPTY (1L<<28) +#define BNX2_RPM_DEBUG2_FM_DISCARD (1L<<29) +#define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D2 (1L<<30) +#define BNX2_RPM_DEBUG2_LAST_RULE_IN_FM_D1 (1L<<31) + +#define BNX2_RPM_DEBUG3 0x00001990 +#define BNX2_RPM_DEBUG3_AVAIL_MBUF_PTR (0x1ffL<<0) +#define BNX2_RPM_DEBUG3_RDE_RLUPQ_WR_REQ_INT (1L<<9) +#define BNX2_RPM_DEBUG3_RDE_RBUF_WR_LAST_INT (1L<<10) +#define BNX2_RPM_DEBUG3_RDE_RBUF_WR_REQ_INT (1L<<11) +#define BNX2_RPM_DEBUG3_RDE_RBUF_FREE_REQ (1L<<12) +#define BNX2_RPM_DEBUG3_RDE_RBUF_ALLOC_REQ (1L<<13) +#define BNX2_RPM_DEBUG3_DFSM_MBUF_NOTAVAIL (1L<<14) +#define BNX2_RPM_DEBUG3_RBUF_RDE_SOF_DROP (1L<<15) +#define BNX2_RPM_DEBUG3_DFIFO_VLD_ENTRY_CT (0xfL<<16) +#define BNX2_RPM_DEBUG3_RDE_SRC_FIFO_ALMFULL (1L<<21) +#define BNX2_RPM_DEBUG3_DROP_NXT_VLD (1L<<22) +#define BNX2_RPM_DEBUG3_DROP_NXT (1L<<23) +#define BNX2_RPM_DEBUG3_FTQ_FSM (0x3L<<24) +#define BNX2_RPM_DEBUG3_FTQ_FSM_IDLE (0x0L<<24) +#define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_ACK (0x1L<<24) +#define BNX2_RPM_DEBUG3_FTQ_FSM_WAIT_FREE (0x2L<<24) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM (0x3L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_SOF (0x0L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_GET_MBUF (0x1L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_DMA_DATA (0x2L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DATA (0x3L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_EOF (0x4L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_MF_ACK (0x5L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_WAIT_DROP_NXT_VLD (0x6L<<26) +#define BNX2_RPM_DEBUG3_MBWRITE_FSM_DONE (0x7L<<26) +#define BNX2_RPM_DEBUG3_MBFREE_FSM (1L<<29) +#define BNX2_RPM_DEBUG3_MBFREE_FSM_IDLE (0L<<29) +#define BNX2_RPM_DEBUG3_MBFREE_FSM_WAIT_ACK (1L<<29) +#define BNX2_RPM_DEBUG3_MBALLOC_FSM (1L<<30) +#define BNX2_RPM_DEBUG3_MBALLOC_FSM_ET_MBUF (0x0L<<30) +#define BNX2_RPM_DEBUG3_MBALLOC_FSM_IVE_MBUF (0x1L<<30) +#define BNX2_RPM_DEBUG3_CCODE_EOF_ERROR (1L<<31) + +#define BNX2_RPM_DEBUG4 0x00001994 +#define BNX2_RPM_DEBUG4_DFSM_MBUF_CLUSTER (0x1ffffffL<<0) +#define BNX2_RPM_DEBUG4_DFIFO_CUR_CCODE (0x7L<<25) +#define BNX2_RPM_DEBUG4_MBWRITE_FSM (0x7L<<28) +#define BNX2_RPM_DEBUG4_DFIFO_EMPTY (1L<<31) + +#define BNX2_RPM_DEBUG5 0x00001998 +#define BNX2_RPM_DEBUG5_RDROP_WPTR (0x1fL<<0) +#define BNX2_RPM_DEBUG5_RDROP_ACPI_RPTR (0x1fL<<5) +#define BNX2_RPM_DEBUG5_RDROP_MC_RPTR (0x1fL<<10) +#define BNX2_RPM_DEBUG5_RDROP_RC_RPTR (0x1fL<<15) +#define BNX2_RPM_DEBUG5_RDROP_ACPI_EMPTY (1L<<20) +#define BNX2_RPM_DEBUG5_RDROP_MC_EMPTY (1L<<21) +#define BNX2_RPM_DEBUG5_RDROP_AEOF_VEC_AT_RDROP_MC_RPTR (1L<<22) +#define BNX2_RPM_DEBUG5_HOLDREG_WOL_DROP_INT (1L<<23) +#define BNX2_RPM_DEBUG5_HOLDREG_DISCARD (1L<<24) +#define BNX2_RPM_DEBUG5_HOLDREG_MBUF_NOTAVAIL (1L<<25) +#define BNX2_RPM_DEBUG5_HOLDREG_MC_EMPTY (1L<<26) +#define BNX2_RPM_DEBUG5_HOLDREG_RC_EMPTY (1L<<27) +#define BNX2_RPM_DEBUG5_HOLDREG_FC_EMPTY (1L<<28) +#define BNX2_RPM_DEBUG5_HOLDREG_ACPI_EMPTY (1L<<29) +#define BNX2_RPM_DEBUG5_HOLDREG_FULL_T (1L<<30) +#define BNX2_RPM_DEBUG5_HOLDREG_RD (1L<<31) + +#define BNX2_RPM_DEBUG6 0x0000199c +#define BNX2_RPM_DEBUG6_ACPI_VEC (0xffffL<<0) +#define BNX2_RPM_DEBUG6_VEC (0xffffL<<16) + +#define BNX2_RPM_DEBUG7 0x000019a0 +#define BNX2_RPM_DEBUG7_RPM_DBG7_LAST_CRC (0xffffffffL<<0) + +#define BNX2_RPM_DEBUG8 0x000019a4 +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM (0xfL<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_IDLE (0L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W1_ADDR (1L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W2_ADDR (2L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_W3_ADDR (3L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_SOF_WAIT_THBUF (4L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_DATA (5L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W0_ADDR (6L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W1_ADDR (7L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W2_ADDR (8L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_W3_ADDR (9L<<0) +#define BNX2_RPM_DEBUG8_PS_ACPI_FSM_WAIT_THBUF (10L<<0) +#define BNX2_RPM_DEBUG8_COMPARE_AT_W0 (1L<<4) +#define BNX2_RPM_DEBUG8_COMPARE_AT_W3_DATA (1L<<5) +#define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_WAIT (1L<<6) +#define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W3 (1L<<7) +#define BNX2_RPM_DEBUG8_COMPARE_AT_SOF_W2 (1L<<8) +#define BNX2_RPM_DEBUG8_EOF_W_LTEQ6_VLDBYTES (1L<<9) +#define BNX2_RPM_DEBUG8_EOF_W_LTEQ4_VLDBYTES (1L<<10) +#define BNX2_RPM_DEBUG8_NXT_EOF_W_12_VLDBYTES (1L<<11) +#define BNX2_RPM_DEBUG8_EOF_DET (1L<<12) +#define BNX2_RPM_DEBUG8_SOF_DET (1L<<13) +#define BNX2_RPM_DEBUG8_WAIT_4_SOF (1L<<14) +#define BNX2_RPM_DEBUG8_ALL_DONE (1L<<15) +#define BNX2_RPM_DEBUG8_THBUF_ADDR (0x7fL<<16) +#define BNX2_RPM_DEBUG8_BYTE_CTR (0xffL<<24) + +#define BNX2_RPM_DEBUG9 0x000019a8 +#define BNX2_RPM_DEBUG9_OUTFIFO_COUNT (0x7L<<0) +#define BNX2_RPM_DEBUG9_RDE_ACPI_RDY (1L<<3) +#define BNX2_RPM_DEBUG9_VLD_RD_ENTRY_CT (0x7L<<4) +#define BNX2_RPM_DEBUG9_OUTFIFO_OVERRUN_OCCURRED (1L<<28) +#define BNX2_RPM_DEBUG9_INFIFO_OVERRUN_OCCURRED (1L<<29) +#define BNX2_RPM_DEBUG9_ACPI_MATCH_INT (1L<<30) +#define BNX2_RPM_DEBUG9_ACPI_ENABLE_SYN (1L<<31) + +#define BNX2_RPM_ACPI_DBG_BUF_W00 0x000019c0 +#define BNX2_RPM_ACPI_DBG_BUF_W01 0x000019c4 +#define BNX2_RPM_ACPI_DBG_BUF_W02 0x000019c8 +#define BNX2_RPM_ACPI_DBG_BUF_W03 0x000019cc +#define BNX2_RPM_ACPI_DBG_BUF_W10 0x000019d0 +#define BNX2_RPM_ACPI_DBG_BUF_W11 0x000019d4 +#define BNX2_RPM_ACPI_DBG_BUF_W12 0x000019d8 +#define BNX2_RPM_ACPI_DBG_BUF_W13 0x000019dc +#define BNX2_RPM_ACPI_DBG_BUF_W20 0x000019e0 +#define BNX2_RPM_ACPI_DBG_BUF_W21 0x000019e4 +#define BNX2_RPM_ACPI_DBG_BUF_W22 0x000019e8 +#define BNX2_RPM_ACPI_DBG_BUF_W23 0x000019ec +#define BNX2_RPM_ACPI_DBG_BUF_W30 0x000019f0 +#define BNX2_RPM_ACPI_DBG_BUF_W31 0x000019f4 +#define BNX2_RPM_ACPI_DBG_BUF_W32 0x000019f8 +#define BNX2_RPM_ACPI_DBG_BUF_W33 0x000019fc + + +/* + * rbuf_reg definition + * offset: 0x200000 + */ +#define BNX2_RBUF_COMMAND 0x00200000 +#define BNX2_RBUF_COMMAND_ENABLED (1L<<0) +#define BNX2_RBUF_COMMAND_FREE_INIT (1L<<1) +#define BNX2_RBUF_COMMAND_RAM_INIT (1L<<2) +#define BNX2_RBUF_COMMAND_OVER_FREE (1L<<4) +#define BNX2_RBUF_COMMAND_ALLOC_REQ (1L<<5) + +#define BNX2_RBUF_STATUS1 0x00200004 +#define BNX2_RBUF_STATUS1_FREE_COUNT (0x3ffL<<0) + +#define BNX2_RBUF_STATUS2 0x00200008 +#define BNX2_RBUF_STATUS2_FREE_TAIL (0x3ffL<<0) +#define BNX2_RBUF_STATUS2_FREE_HEAD (0x3ffL<<16) + +#define BNX2_RBUF_CONFIG 0x0020000c +#define BNX2_RBUF_CONFIG_XOFF_TRIP (0x3ffL<<0) +#define BNX2_RBUF_CONFIG_XON_TRIP (0x3ffL<<16) + +#define BNX2_RBUF_FW_BUF_ALLOC 0x00200010 +#define BNX2_RBUF_FW_BUF_ALLOC_VALUE (0x1ffL<<7) + +#define BNX2_RBUF_FW_BUF_FREE 0x00200014 +#define BNX2_RBUF_FW_BUF_FREE_COUNT (0x7fL<<0) +#define BNX2_RBUF_FW_BUF_FREE_TAIL (0x1ffL<<7) +#define BNX2_RBUF_FW_BUF_FREE_HEAD (0x1ffL<<16) + +#define BNX2_RBUF_FW_BUF_SEL 0x00200018 +#define BNX2_RBUF_FW_BUF_SEL_COUNT (0x7fL<<0) +#define BNX2_RBUF_FW_BUF_SEL_TAIL (0x1ffL<<7) +#define BNX2_RBUF_FW_BUF_SEL_HEAD (0x1ffL<<16) + +#define BNX2_RBUF_CONFIG2 0x0020001c +#define BNX2_RBUF_CONFIG2_MAC_DROP_TRIP (0x3ffL<<0) +#define BNX2_RBUF_CONFIG2_MAC_KEEP_TRIP (0x3ffL<<16) + +#define BNX2_RBUF_CONFIG3 0x00200020 +#define BNX2_RBUF_CONFIG3_CU_DROP_TRIP (0x3ffL<<0) +#define BNX2_RBUF_CONFIG3_CU_KEEP_TRIP (0x3ffL<<16) + +#define BNX2_RBUF_PKT_DATA 0x00208000 +#define BNX2_RBUF_CLIST_DATA 0x00210000 +#define BNX2_RBUF_BUF_DATA 0x00220000 + + +/* + * rv2p_reg definition + * offset: 0x2800 + */ +#define BNX2_RV2P_COMMAND 0x00002800 +#define BNX2_RV2P_COMMAND_ENABLED (1L<<0) +#define BNX2_RV2P_COMMAND_PROC1_INTRPT (1L<<1) +#define BNX2_RV2P_COMMAND_PROC2_INTRPT (1L<<2) +#define BNX2_RV2P_COMMAND_ABORT0 (1L<<4) +#define BNX2_RV2P_COMMAND_ABORT1 (1L<<5) +#define BNX2_RV2P_COMMAND_ABORT2 (1L<<6) +#define BNX2_RV2P_COMMAND_ABORT3 (1L<<7) +#define BNX2_RV2P_COMMAND_ABORT4 (1L<<8) +#define BNX2_RV2P_COMMAND_ABORT5 (1L<<9) +#define BNX2_RV2P_COMMAND_PROC1_RESET (1L<<16) +#define BNX2_RV2P_COMMAND_PROC2_RESET (1L<<17) +#define BNX2_RV2P_COMMAND_CTXIF_RESET (1L<<18) + +#define BNX2_RV2P_STATUS 0x00002804 +#define BNX2_RV2P_STATUS_ALWAYS_0 (1L<<0) +#define BNX2_RV2P_STATUS_RV2P_GEN_STAT0_CNT (1L<<8) +#define BNX2_RV2P_STATUS_RV2P_GEN_STAT1_CNT (1L<<9) +#define BNX2_RV2P_STATUS_RV2P_GEN_STAT2_CNT (1L<<10) +#define BNX2_RV2P_STATUS_RV2P_GEN_STAT3_CNT (1L<<11) +#define BNX2_RV2P_STATUS_RV2P_GEN_STAT4_CNT (1L<<12) +#define BNX2_RV2P_STATUS_RV2P_GEN_STAT5_CNT (1L<<13) + +#define BNX2_RV2P_CONFIG 0x00002808 +#define BNX2_RV2P_CONFIG_STALL_PROC1 (1L<<0) +#define BNX2_RV2P_CONFIG_STALL_PROC2 (1L<<1) +#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT0 (1L<<8) +#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT1 (1L<<9) +#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT2 (1L<<10) +#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT3 (1L<<11) +#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT4 (1L<<12) +#define BNX2_RV2P_CONFIG_PROC1_STALL_ON_ABORT5 (1L<<13) +#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT0 (1L<<16) +#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT1 (1L<<17) +#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT2 (1L<<18) +#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT3 (1L<<19) +#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT4 (1L<<20) +#define BNX2_RV2P_CONFIG_PROC2_STALL_ON_ABORT5 (1L<<21) +#define BNX2_RV2P_CONFIG_PAGE_SIZE (0xfL<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_256 (0L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_512 (1L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_1K (2L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_2K (3L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_4K (4L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_8K (5L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_16K (6L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_32K (7L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_64K (8L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_128K (9L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_256K (10L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_512K (11L<<24) +#define BNX2_RV2P_CONFIG_PAGE_SIZE_1M (12L<<24) + +#define BNX2_RV2P_GEN_BFR_ADDR_0 0x00002810 +#define BNX2_RV2P_GEN_BFR_ADDR_0_VALUE (0xffffL<<16) + +#define BNX2_RV2P_GEN_BFR_ADDR_1 0x00002814 +#define BNX2_RV2P_GEN_BFR_ADDR_1_VALUE (0xffffL<<16) + +#define BNX2_RV2P_GEN_BFR_ADDR_2 0x00002818 +#define BNX2_RV2P_GEN_BFR_ADDR_2_VALUE (0xffffL<<16) + +#define BNX2_RV2P_GEN_BFR_ADDR_3 0x0000281c +#define BNX2_RV2P_GEN_BFR_ADDR_3_VALUE (0xffffL<<16) + +#define BNX2_RV2P_INSTR_HIGH 0x00002830 +#define BNX2_RV2P_INSTR_HIGH_HIGH (0x1fL<<0) + +#define BNX2_RV2P_INSTR_LOW 0x00002834 +#define BNX2_RV2P_PROC1_ADDR_CMD 0x00002838 +#define BNX2_RV2P_PROC1_ADDR_CMD_ADD (0x3ffL<<0) +#define BNX2_RV2P_PROC1_ADDR_CMD_RDWR (1L<<31) + +#define BNX2_RV2P_PROC2_ADDR_CMD 0x0000283c +#define BNX2_RV2P_PROC2_ADDR_CMD_ADD (0x3ffL<<0) +#define BNX2_RV2P_PROC2_ADDR_CMD_RDWR (1L<<31) + +#define BNX2_RV2P_PROC1_GRC_DEBUG 0x00002840 +#define BNX2_RV2P_PROC2_GRC_DEBUG 0x00002844 +#define BNX2_RV2P_GRC_PROC_DEBUG 0x00002848 +#define BNX2_RV2P_DEBUG_VECT_PEEK 0x0000284c +#define BNX2_RV2P_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_RV2P_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_RV2P_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_RV2P_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_RV2P_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_RV2P_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_RV2P_PFTQ_DATA 0x00002b40 +#define BNX2_RV2P_PFTQ_CMD 0x00002b78 +#define BNX2_RV2P_PFTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_RV2P_PFTQ_CMD_WR_TOP (1L<<10) +#define BNX2_RV2P_PFTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_RV2P_PFTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_RV2P_PFTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_RV2P_PFTQ_CMD_RD_DATA (1L<<26) +#define BNX2_RV2P_PFTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_RV2P_PFTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_RV2P_PFTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_RV2P_PFTQ_CMD_POP (1L<<30) +#define BNX2_RV2P_PFTQ_CMD_BUSY (1L<<31) + +#define BNX2_RV2P_PFTQ_CTL 0x00002b7c +#define BNX2_RV2P_PFTQ_CTL_INTERVENE (1L<<0) +#define BNX2_RV2P_PFTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_RV2P_PFTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_RV2P_PFTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_RV2P_PFTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_RV2P_TFTQ_DATA 0x00002b80 +#define BNX2_RV2P_TFTQ_CMD 0x00002bb8 +#define BNX2_RV2P_TFTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_RV2P_TFTQ_CMD_WR_TOP (1L<<10) +#define BNX2_RV2P_TFTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_RV2P_TFTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_RV2P_TFTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_RV2P_TFTQ_CMD_RD_DATA (1L<<26) +#define BNX2_RV2P_TFTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_RV2P_TFTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_RV2P_TFTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_RV2P_TFTQ_CMD_POP (1L<<30) +#define BNX2_RV2P_TFTQ_CMD_BUSY (1L<<31) + +#define BNX2_RV2P_TFTQ_CTL 0x00002bbc +#define BNX2_RV2P_TFTQ_CTL_INTERVENE (1L<<0) +#define BNX2_RV2P_TFTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_RV2P_TFTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_RV2P_TFTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_RV2P_TFTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_RV2P_MFTQ_DATA 0x00002bc0 +#define BNX2_RV2P_MFTQ_CMD 0x00002bf8 +#define BNX2_RV2P_MFTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_RV2P_MFTQ_CMD_WR_TOP (1L<<10) +#define BNX2_RV2P_MFTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_RV2P_MFTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_RV2P_MFTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_RV2P_MFTQ_CMD_RD_DATA (1L<<26) +#define BNX2_RV2P_MFTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_RV2P_MFTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_RV2P_MFTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_RV2P_MFTQ_CMD_POP (1L<<30) +#define BNX2_RV2P_MFTQ_CMD_BUSY (1L<<31) + +#define BNX2_RV2P_MFTQ_CTL 0x00002bfc +#define BNX2_RV2P_MFTQ_CTL_INTERVENE (1L<<0) +#define BNX2_RV2P_MFTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_RV2P_MFTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_RV2P_MFTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_RV2P_MFTQ_CTL_CUR_DEPTH (0x3ffL<<22) + + + +/* + * mq_reg definition + * offset: 0x3c00 + */ +#define BNX2_MQ_COMMAND 0x00003c00 +#define BNX2_MQ_COMMAND_ENABLED (1L<<0) +#define BNX2_MQ_COMMAND_OVERFLOW (1L<<4) +#define BNX2_MQ_COMMAND_WR_ERROR (1L<<5) +#define BNX2_MQ_COMMAND_RD_ERROR (1L<<6) + +#define BNX2_MQ_STATUS 0x00003c04 +#define BNX2_MQ_STATUS_CTX_ACCESS_STAT (1L<<16) +#define BNX2_MQ_STATUS_CTX_ACCESS64_STAT (1L<<17) +#define BNX2_MQ_STATUS_PCI_STALL_STAT (1L<<18) + +#define BNX2_MQ_CONFIG 0x00003c08 +#define BNX2_MQ_CONFIG_TX_HIGH_PRI (1L<<0) +#define BNX2_MQ_CONFIG_HALT_DIS (1L<<1) +#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE (0x7L<<4) +#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_256 (0L<<4) +#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_512 (1L<<4) +#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_1K (2L<<4) +#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_2K (3L<<4) +#define BNX2_MQ_CONFIG_KNL_BYP_BLK_SIZE_4K (4L<<4) +#define BNX2_MQ_CONFIG_MAX_DEPTH (0x7fL<<8) +#define BNX2_MQ_CONFIG_CUR_DEPTH (0x7fL<<20) + +#define BNX2_MQ_ENQUEUE1 0x00003c0c +#define BNX2_MQ_ENQUEUE1_OFFSET (0x3fL<<2) +#define BNX2_MQ_ENQUEUE1_CID (0x3fffL<<8) +#define BNX2_MQ_ENQUEUE1_BYTE_MASK (0xfL<<24) +#define BNX2_MQ_ENQUEUE1_KNL_MODE (1L<<28) + +#define BNX2_MQ_ENQUEUE2 0x00003c10 +#define BNX2_MQ_BAD_WR_ADDR 0x00003c14 +#define BNX2_MQ_BAD_RD_ADDR 0x00003c18 +#define BNX2_MQ_KNL_BYP_WIND_START 0x00003c1c +#define BNX2_MQ_KNL_BYP_WIND_START_VALUE (0xfffffL<<12) + +#define BNX2_MQ_KNL_WIND_END 0x00003c20 +#define BNX2_MQ_KNL_WIND_END_VALUE (0xffffffL<<8) + +#define BNX2_MQ_KNL_WRITE_MASK1 0x00003c24 +#define BNX2_MQ_KNL_TX_MASK1 0x00003c28 +#define BNX2_MQ_KNL_CMD_MASK1 0x00003c2c +#define BNX2_MQ_KNL_COND_ENQUEUE_MASK1 0x00003c30 +#define BNX2_MQ_KNL_RX_V2P_MASK1 0x00003c34 +#define BNX2_MQ_KNL_WRITE_MASK2 0x00003c38 +#define BNX2_MQ_KNL_TX_MASK2 0x00003c3c +#define BNX2_MQ_KNL_CMD_MASK2 0x00003c40 +#define BNX2_MQ_KNL_COND_ENQUEUE_MASK2 0x00003c44 +#define BNX2_MQ_KNL_RX_V2P_MASK2 0x00003c48 +#define BNX2_MQ_KNL_BYP_WRITE_MASK1 0x00003c4c +#define BNX2_MQ_KNL_BYP_TX_MASK1 0x00003c50 +#define BNX2_MQ_KNL_BYP_CMD_MASK1 0x00003c54 +#define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK1 0x00003c58 +#define BNX2_MQ_KNL_BYP_RX_V2P_MASK1 0x00003c5c +#define BNX2_MQ_KNL_BYP_WRITE_MASK2 0x00003c60 +#define BNX2_MQ_KNL_BYP_TX_MASK2 0x00003c64 +#define BNX2_MQ_KNL_BYP_CMD_MASK2 0x00003c68 +#define BNX2_MQ_KNL_BYP_COND_ENQUEUE_MASK2 0x00003c6c +#define BNX2_MQ_KNL_BYP_RX_V2P_MASK2 0x00003c70 +#define BNX2_MQ_MEM_WR_ADDR 0x00003c74 +#define BNX2_MQ_MEM_WR_ADDR_VALUE (0x3fL<<0) + +#define BNX2_MQ_MEM_WR_DATA0 0x00003c78 +#define BNX2_MQ_MEM_WR_DATA0_VALUE (0xffffffffL<<0) + +#define BNX2_MQ_MEM_WR_DATA1 0x00003c7c +#define BNX2_MQ_MEM_WR_DATA1_VALUE (0xffffffffL<<0) + +#define BNX2_MQ_MEM_WR_DATA2 0x00003c80 +#define BNX2_MQ_MEM_WR_DATA2_VALUE (0x3fffffffL<<0) + +#define BNX2_MQ_MEM_RD_ADDR 0x00003c84 +#define BNX2_MQ_MEM_RD_ADDR_VALUE (0x3fL<<0) + +#define BNX2_MQ_MEM_RD_DATA0 0x00003c88 +#define BNX2_MQ_MEM_RD_DATA0_VALUE (0xffffffffL<<0) + +#define BNX2_MQ_MEM_RD_DATA1 0x00003c8c +#define BNX2_MQ_MEM_RD_DATA1_VALUE (0xffffffffL<<0) + +#define BNX2_MQ_MEM_RD_DATA2 0x00003c90 +#define BNX2_MQ_MEM_RD_DATA2_VALUE (0x3fffffffL<<0) + + + +/* + * tbdr_reg definition + * offset: 0x5000 + */ +#define BNX2_TBDR_COMMAND 0x00005000 +#define BNX2_TBDR_COMMAND_ENABLE (1L<<0) +#define BNX2_TBDR_COMMAND_SOFT_RST (1L<<1) +#define BNX2_TBDR_COMMAND_MSTR_ABORT (1L<<4) + +#define BNX2_TBDR_STATUS 0x00005004 +#define BNX2_TBDR_STATUS_DMA_WAIT (1L<<0) +#define BNX2_TBDR_STATUS_FTQ_WAIT (1L<<1) +#define BNX2_TBDR_STATUS_FIFO_OVERFLOW (1L<<2) +#define BNX2_TBDR_STATUS_FIFO_UNDERFLOW (1L<<3) +#define BNX2_TBDR_STATUS_SEARCHMISS_ERROR (1L<<4) +#define BNX2_TBDR_STATUS_FTQ_ENTRY_CNT (1L<<5) +#define BNX2_TBDR_STATUS_BURST_CNT (1L<<6) + +#define BNX2_TBDR_CONFIG 0x00005008 +#define BNX2_TBDR_CONFIG_MAX_BDS (0xffL<<0) +#define BNX2_TBDR_CONFIG_SWAP_MODE (1L<<8) +#define BNX2_TBDR_CONFIG_PRIORITY (1L<<9) +#define BNX2_TBDR_CONFIG_CACHE_NEXT_PAGE_PTRS (1L<<10) +#define BNX2_TBDR_CONFIG_PAGE_SIZE (0xfL<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_256 (0L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_512 (1L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_1K (2L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_2K (3L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_4K (4L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_8K (5L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_16K (6L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_32K (7L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_64K (8L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_128K (9L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_256K (10L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_512K (11L<<24) +#define BNX2_TBDR_CONFIG_PAGE_SIZE_1M (12L<<24) + +#define BNX2_TBDR_DEBUG_VECT_PEEK 0x0000500c +#define BNX2_TBDR_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_TBDR_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_TBDR_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_TBDR_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_TBDR_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_TBDR_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_TBDR_FTQ_DATA 0x000053c0 +#define BNX2_TBDR_FTQ_CMD 0x000053f8 +#define BNX2_TBDR_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_TBDR_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_TBDR_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_TBDR_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_TBDR_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_TBDR_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_TBDR_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_TBDR_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_TBDR_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_TBDR_FTQ_CMD_POP (1L<<30) +#define BNX2_TBDR_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_TBDR_FTQ_CTL 0x000053fc +#define BNX2_TBDR_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_TBDR_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_TBDR_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_TBDR_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_TBDR_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + + + +/* + * tdma_reg definition + * offset: 0x5c00 + */ +#define BNX2_TDMA_COMMAND 0x00005c00 +#define BNX2_TDMA_COMMAND_ENABLED (1L<<0) +#define BNX2_TDMA_COMMAND_MASTER_ABORT (1L<<4) +#define BNX2_TDMA_COMMAND_BAD_L2_LENGTH_ABORT (1L<<7) + +#define BNX2_TDMA_STATUS 0x00005c04 +#define BNX2_TDMA_STATUS_DMA_WAIT (1L<<0) +#define BNX2_TDMA_STATUS_PAYLOAD_WAIT (1L<<1) +#define BNX2_TDMA_STATUS_PATCH_FTQ_WAIT (1L<<2) +#define BNX2_TDMA_STATUS_LOCK_WAIT (1L<<3) +#define BNX2_TDMA_STATUS_FTQ_ENTRY_CNT (1L<<16) +#define BNX2_TDMA_STATUS_BURST_CNT (1L<<17) + +#define BNX2_TDMA_CONFIG 0x00005c08 +#define BNX2_TDMA_CONFIG_ONE_DMA (1L<<0) +#define BNX2_TDMA_CONFIG_ONE_RECORD (1L<<1) +#define BNX2_TDMA_CONFIG_LIMIT_SZ (0xfL<<4) +#define BNX2_TDMA_CONFIG_LIMIT_SZ_64 (0L<<4) +#define BNX2_TDMA_CONFIG_LIMIT_SZ_128 (0x4L<<4) +#define BNX2_TDMA_CONFIG_LIMIT_SZ_256 (0x6L<<4) +#define BNX2_TDMA_CONFIG_LIMIT_SZ_512 (0x8L<<4) +#define BNX2_TDMA_CONFIG_LINE_SZ (0xfL<<8) +#define BNX2_TDMA_CONFIG_LINE_SZ_64 (0L<<8) +#define BNX2_TDMA_CONFIG_LINE_SZ_128 (4L<<8) +#define BNX2_TDMA_CONFIG_LINE_SZ_256 (6L<<8) +#define BNX2_TDMA_CONFIG_LINE_SZ_512 (8L<<8) +#define BNX2_TDMA_CONFIG_ALIGN_ENA (1L<<15) +#define BNX2_TDMA_CONFIG_CHK_L2_BD (1L<<16) +#define BNX2_TDMA_CONFIG_FIFO_CMP (0xfL<<20) + +#define BNX2_TDMA_PAYLOAD_PROD 0x00005c0c +#define BNX2_TDMA_PAYLOAD_PROD_VALUE (0x1fffL<<3) + +#define BNX2_TDMA_DBG_WATCHDOG 0x00005c10 +#define BNX2_TDMA_DBG_TRIGGER 0x00005c14 +#define BNX2_TDMA_DMAD_FSM 0x00005c80 +#define BNX2_TDMA_DMAD_FSM_BD_INVLD (1L<<0) +#define BNX2_TDMA_DMAD_FSM_PUSH (0xfL<<4) +#define BNX2_TDMA_DMAD_FSM_ARB_TBDC (0x3L<<8) +#define BNX2_TDMA_DMAD_FSM_ARB_CTX (1L<<12) +#define BNX2_TDMA_DMAD_FSM_DR_INTF (1L<<16) +#define BNX2_TDMA_DMAD_FSM_DMAD (0x7L<<20) +#define BNX2_TDMA_DMAD_FSM_BD (0xfL<<24) + +#define BNX2_TDMA_DMAD_STATUS 0x00005c84 +#define BNX2_TDMA_DMAD_STATUS_RHOLD_PUSH_ENTRY (0x3L<<0) +#define BNX2_TDMA_DMAD_STATUS_RHOLD_DMAD_ENTRY (0x3L<<4) +#define BNX2_TDMA_DMAD_STATUS_RHOLD_BD_ENTRY (0x3L<<8) +#define BNX2_TDMA_DMAD_STATUS_IFTQ_ENUM (0xfL<<12) + +#define BNX2_TDMA_DR_INTF_FSM 0x00005c88 +#define BNX2_TDMA_DR_INTF_FSM_L2_COMP (0x3L<<0) +#define BNX2_TDMA_DR_INTF_FSM_TPATQ (0x7L<<4) +#define BNX2_TDMA_DR_INTF_FSM_TPBUF (0x3L<<8) +#define BNX2_TDMA_DR_INTF_FSM_DR_BUF (0x7L<<12) +#define BNX2_TDMA_DR_INTF_FSM_DMAD (0x7L<<16) + +#define BNX2_TDMA_DR_INTF_STATUS 0x00005c8c +#define BNX2_TDMA_DR_INTF_STATUS_HOLE_PHASE (0x7L<<0) +#define BNX2_TDMA_DR_INTF_STATUS_DATA_AVAIL (0x3L<<4) +#define BNX2_TDMA_DR_INTF_STATUS_SHIFT_ADDR (0x7L<<8) +#define BNX2_TDMA_DR_INTF_STATUS_NXT_PNTR (0xfL<<12) +#define BNX2_TDMA_DR_INTF_STATUS_BYTE_COUNT (0x7L<<16) + +#define BNX2_TDMA_FTQ_DATA 0x00005fc0 +#define BNX2_TDMA_FTQ_CMD 0x00005ff8 +#define BNX2_TDMA_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_TDMA_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_TDMA_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_TDMA_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_TDMA_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_TDMA_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_TDMA_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_TDMA_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_TDMA_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_TDMA_FTQ_CMD_POP (1L<<30) +#define BNX2_TDMA_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_TDMA_FTQ_CTL 0x00005ffc +#define BNX2_TDMA_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_TDMA_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_TDMA_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_TDMA_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_TDMA_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + + + +/* + * hc_reg definition + * offset: 0x6800 + */ +#define BNX2_HC_COMMAND 0x00006800 +#define BNX2_HC_COMMAND_ENABLE (1L<<0) +#define BNX2_HC_COMMAND_SKIP_ABORT (1L<<4) +#define BNX2_HC_COMMAND_COAL_NOW (1L<<16) +#define BNX2_HC_COMMAND_COAL_NOW_WO_INT (1L<<17) +#define BNX2_HC_COMMAND_STATS_NOW (1L<<18) +#define BNX2_HC_COMMAND_FORCE_INT (0x3L<<19) +#define BNX2_HC_COMMAND_FORCE_INT_NULL (0L<<19) +#define BNX2_HC_COMMAND_FORCE_INT_HIGH (1L<<19) +#define BNX2_HC_COMMAND_FORCE_INT_LOW (2L<<19) +#define BNX2_HC_COMMAND_FORCE_INT_FREE (3L<<19) +#define BNX2_HC_COMMAND_CLR_STAT_NOW (1L<<21) + +#define BNX2_HC_STATUS 0x00006804 +#define BNX2_HC_STATUS_MASTER_ABORT (1L<<0) +#define BNX2_HC_STATUS_PARITY_ERROR_STATE (1L<<1) +#define BNX2_HC_STATUS_PCI_CLK_CNT_STAT (1L<<16) +#define BNX2_HC_STATUS_CORE_CLK_CNT_STAT (1L<<17) +#define BNX2_HC_STATUS_NUM_STATUS_BLOCKS_STAT (1L<<18) +#define BNX2_HC_STATUS_NUM_INT_GEN_STAT (1L<<19) +#define BNX2_HC_STATUS_NUM_INT_MBOX_WR_STAT (1L<<20) +#define BNX2_HC_STATUS_CORE_CLKS_TO_HW_INTACK_STAT (1L<<23) +#define BNX2_HC_STATUS_CORE_CLKS_TO_SW_INTACK_STAT (1L<<24) +#define BNX2_HC_STATUS_CORE_CLKS_DURING_SW_INTACK_STAT (1L<<25) + +#define BNX2_HC_CONFIG 0x00006808 +#define BNX2_HC_CONFIG_COLLECT_STATS (1L<<0) +#define BNX2_HC_CONFIG_RX_TMR_MODE (1L<<1) +#define BNX2_HC_CONFIG_TX_TMR_MODE (1L<<2) +#define BNX2_HC_CONFIG_COM_TMR_MODE (1L<<3) +#define BNX2_HC_CONFIG_CMD_TMR_MODE (1L<<4) +#define BNX2_HC_CONFIG_STATISTIC_PRIORITY (1L<<5) +#define BNX2_HC_CONFIG_STATUS_PRIORITY (1L<<6) +#define BNX2_HC_CONFIG_STAT_MEM_ADDR (0xffL<<8) + +#define BNX2_HC_ATTN_BITS_ENABLE 0x0000680c +#define BNX2_HC_STATUS_ADDR_L 0x00006810 +#define BNX2_HC_STATUS_ADDR_H 0x00006814 +#define BNX2_HC_STATISTICS_ADDR_L 0x00006818 +#define BNX2_HC_STATISTICS_ADDR_H 0x0000681c +#define BNX2_HC_TX_QUICK_CONS_TRIP 0x00006820 +#define BNX2_HC_TX_QUICK_CONS_TRIP_VALUE (0xffL<<0) +#define BNX2_HC_TX_QUICK_CONS_TRIP_INT (0xffL<<16) + +#define BNX2_HC_COMP_PROD_TRIP 0x00006824 +#define BNX2_HC_COMP_PROD_TRIP_VALUE (0xffL<<0) +#define BNX2_HC_COMP_PROD_TRIP_INT (0xffL<<16) + +#define BNX2_HC_RX_QUICK_CONS_TRIP 0x00006828 +#define BNX2_HC_RX_QUICK_CONS_TRIP_VALUE (0xffL<<0) +#define BNX2_HC_RX_QUICK_CONS_TRIP_INT (0xffL<<16) + +#define BNX2_HC_RX_TICKS 0x0000682c +#define BNX2_HC_RX_TICKS_VALUE (0x3ffL<<0) +#define BNX2_HC_RX_TICKS_INT (0x3ffL<<16) + +#define BNX2_HC_TX_TICKS 0x00006830 +#define BNX2_HC_TX_TICKS_VALUE (0x3ffL<<0) +#define BNX2_HC_TX_TICKS_INT (0x3ffL<<16) + +#define BNX2_HC_COM_TICKS 0x00006834 +#define BNX2_HC_COM_TICKS_VALUE (0x3ffL<<0) +#define BNX2_HC_COM_TICKS_INT (0x3ffL<<16) + +#define BNX2_HC_CMD_TICKS 0x00006838 +#define BNX2_HC_CMD_TICKS_VALUE (0x3ffL<<0) +#define BNX2_HC_CMD_TICKS_INT (0x3ffL<<16) + +#define BNX2_HC_PERIODIC_TICKS 0x0000683c +#define BNX2_HC_PERIODIC_TICKS_HC_PERIODIC_TICKS (0xffffL<<0) + +#define BNX2_HC_STAT_COLLECT_TICKS 0x00006840 +#define BNX2_HC_STAT_COLLECT_TICKS_HC_STAT_COLL_TICKS (0xffL<<4) + +#define BNX2_HC_STATS_TICKS 0x00006844 +#define BNX2_HC_STATS_TICKS_HC_STAT_TICKS (0xffffL<<8) + +#define BNX2_HC_STAT_MEM_DATA 0x0000684c +#define BNX2_HC_STAT_GEN_SEL_0 0x00006850 +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0 (0x7fL<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT0 (0L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT1 (1L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT2 (2L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT3 (3L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT4 (4L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT5 (5L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT6 (6L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT7 (7L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT8 (8L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT9 (9L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT10 (10L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXP_STAT11 (11L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT0 (12L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT1 (13L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT2 (14L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT3 (15L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT4 (16L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT5 (17L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT6 (18L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXP_STAT7 (19L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT0 (20L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT1 (21L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT2 (22L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT3 (23L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT4 (24L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT5 (25L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT6 (26L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT7 (27L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT8 (28L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT9 (29L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT10 (30L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COM_STAT11 (31L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT0 (32L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT1 (33L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT2 (34L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPAT_STAT3 (35L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT0 (36L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT1 (37L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT2 (38L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT3 (39L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT4 (40L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT5 (41L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT6 (42L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CP_STAT7 (43L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT0 (44L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT1 (45L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT2 (46L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT3 (47L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT4 (48L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT5 (49L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT6 (50L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MCP_STAT7 (51L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_PCI_CLK_CNT (52L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CORE_CLK_CNT (53L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_STATUS_BLOCKS (54L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_GEN (55L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_NUM_INT_MBOX_WR (56L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_HW_INTACK (59L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_TO_SW_INTACK (60L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_HC_CORE_CLKS_DURING_SW_INTACK (61L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_CMD_CNT (62L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCH_SLOT_CNT (63L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_CMD_CNT (64L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSCH_SLOT_CNT (65L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT (66L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT (67L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT (68L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT (69L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT (70L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT (71L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT (72L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT (73L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT (74L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT (75L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT (76L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT (77L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT (78L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT (79L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT (80L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT (81L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT (82L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT (83L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT (84L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_TRANSFERS_CNT (85L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_READ_DELAY_PCI_CLKS_CNT (86L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_TRANSFERS_CNT (87L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_DELAY_PCI_CLKS_CNT (88L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_READ_RETRY_AFTER_DATA_CNT (89L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_TRANSFERS_CNT (90L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_WRITE_DELAY_PCI_CLKS_CNT (91L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_TRANSFERS_CNT (92L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_DELAY_PCI_CLKS_CNT (93L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_DMAE_BIG_WRITE_RETRY_AFTER_DATA_CNT (94L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_WR_CNT64 (95L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_RD_CNT64 (96L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_ACC_STALL_CLKS (97L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_CTX_LOCK_STALL_CLKS (98L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS_STAT (99L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_CTX_ACCESS64_STAT (100L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_MBQ_PCI_STALL_STAT (101L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_FTQ_ENTRY_CNT (102L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDR_BURST_CNT (103L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_FTQ_ENTRY_CNT (104L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMA_BURST_CNT (105L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_FTQ_ENTRY_CNT (106L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMA_BURST_CNT (107L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUP_MATCH_CNT (108L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_POLL_PASS_CNT (109L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR1_CNT (110L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR2_CNT (111L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR3_CNT (112L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR4_CNT (113L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_TMR_TMR5_CNT (114L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT0 (115L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT1 (116L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT2 (117L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT3 (118L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT4 (119L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2P_STAT5 (120L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC1_MISS (121L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_PROC2_MISS (122L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_0_RBDC_BURST_CNT (127L<<0) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_1 (0x7fL<<8) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_2 (0x7fL<<16) +#define BNX2_HC_STAT_GEN_SEL_0_GEN_SEL_3 (0x7fL<<24) + +#define BNX2_HC_STAT_GEN_SEL_1 0x00006854 +#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_4 (0x7fL<<0) +#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_5 (0x7fL<<8) +#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_6 (0x7fL<<16) +#define BNX2_HC_STAT_GEN_SEL_1_GEN_SEL_7 (0x7fL<<24) + +#define BNX2_HC_STAT_GEN_SEL_2 0x00006858 +#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_8 (0x7fL<<0) +#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_9 (0x7fL<<8) +#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_10 (0x7fL<<16) +#define BNX2_HC_STAT_GEN_SEL_2_GEN_SEL_11 (0x7fL<<24) + +#define BNX2_HC_STAT_GEN_SEL_3 0x0000685c +#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_12 (0x7fL<<0) +#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_13 (0x7fL<<8) +#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_14 (0x7fL<<16) +#define BNX2_HC_STAT_GEN_SEL_3_GEN_SEL_15 (0x7fL<<24) + +#define BNX2_HC_STAT_GEN_STAT0 0x00006888 +#define BNX2_HC_STAT_GEN_STAT1 0x0000688c +#define BNX2_HC_STAT_GEN_STAT2 0x00006890 +#define BNX2_HC_STAT_GEN_STAT3 0x00006894 +#define BNX2_HC_STAT_GEN_STAT4 0x00006898 +#define BNX2_HC_STAT_GEN_STAT5 0x0000689c +#define BNX2_HC_STAT_GEN_STAT6 0x000068a0 +#define BNX2_HC_STAT_GEN_STAT7 0x000068a4 +#define BNX2_HC_STAT_GEN_STAT8 0x000068a8 +#define BNX2_HC_STAT_GEN_STAT9 0x000068ac +#define BNX2_HC_STAT_GEN_STAT10 0x000068b0 +#define BNX2_HC_STAT_GEN_STAT11 0x000068b4 +#define BNX2_HC_STAT_GEN_STAT12 0x000068b8 +#define BNX2_HC_STAT_GEN_STAT13 0x000068bc +#define BNX2_HC_STAT_GEN_STAT14 0x000068c0 +#define BNX2_HC_STAT_GEN_STAT15 0x000068c4 +#define BNX2_HC_STAT_GEN_STAT_AC0 0x000068c8 +#define BNX2_HC_STAT_GEN_STAT_AC1 0x000068cc +#define BNX2_HC_STAT_GEN_STAT_AC2 0x000068d0 +#define BNX2_HC_STAT_GEN_STAT_AC3 0x000068d4 +#define BNX2_HC_STAT_GEN_STAT_AC4 0x000068d8 +#define BNX2_HC_STAT_GEN_STAT_AC5 0x000068dc +#define BNX2_HC_STAT_GEN_STAT_AC6 0x000068e0 +#define BNX2_HC_STAT_GEN_STAT_AC7 0x000068e4 +#define BNX2_HC_STAT_GEN_STAT_AC8 0x000068e8 +#define BNX2_HC_STAT_GEN_STAT_AC9 0x000068ec +#define BNX2_HC_STAT_GEN_STAT_AC10 0x000068f0 +#define BNX2_HC_STAT_GEN_STAT_AC11 0x000068f4 +#define BNX2_HC_STAT_GEN_STAT_AC12 0x000068f8 +#define BNX2_HC_STAT_GEN_STAT_AC13 0x000068fc +#define BNX2_HC_STAT_GEN_STAT_AC14 0x00006900 +#define BNX2_HC_STAT_GEN_STAT_AC15 0x00006904 +#define BNX2_HC_VIS 0x00006908 +#define BNX2_HC_VIS_STAT_BUILD_STATE (0xfL<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_IDLE (0L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_START (1L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_REQUEST (2L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE64 (3L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE32 (4L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_UPDATE_DONE (5L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_DMA (6L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_CONTROL (7L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_LOW (8L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_HIGH (9L<<0) +#define BNX2_HC_VIS_STAT_BUILD_STATE_MSI_DATA (10L<<0) +#define BNX2_HC_VIS_DMA_STAT_STATE (0xfL<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_IDLE (0L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_PARAM (1L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_STATUS_DMA (2L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP (3L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_COMP (4L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_PARAM (5L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_STATISTIC_DMA (6L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_1 (7L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_WRITE_COMP_2 (8L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_WAIT (9L<<8) +#define BNX2_HC_VIS_DMA_STAT_STATE_ABORT (15L<<8) +#define BNX2_HC_VIS_DMA_MSI_STATE (0x7L<<12) +#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE (0x3L<<15) +#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_IDLE (0L<<15) +#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_COUNT (1L<<15) +#define BNX2_HC_VIS_STATISTIC_DMA_EN_STATE_START (2L<<15) + +#define BNX2_HC_VIS_1 0x0000690c +#define BNX2_HC_VIS_1_HW_INTACK_STATE (1L<<4) +#define BNX2_HC_VIS_1_HW_INTACK_STATE_IDLE (0L<<4) +#define BNX2_HC_VIS_1_HW_INTACK_STATE_COUNT (1L<<4) +#define BNX2_HC_VIS_1_SW_INTACK_STATE (1L<<5) +#define BNX2_HC_VIS_1_SW_INTACK_STATE_IDLE (0L<<5) +#define BNX2_HC_VIS_1_SW_INTACK_STATE_COUNT (1L<<5) +#define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE (1L<<6) +#define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_IDLE (0L<<6) +#define BNX2_HC_VIS_1_DURING_SW_INTACK_STATE_COUNT (1L<<6) +#define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE (1L<<7) +#define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_IDLE (0L<<7) +#define BNX2_HC_VIS_1_MAILBOX_COUNT_STATE_COUNT (1L<<7) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE (0xfL<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_IDLE (0L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_DMA (1L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_UPDATE (2L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_ASSIGN (3L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_WAIT (4L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_UPDATE (5L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_ASSIGN (6L<<17) +#define BNX2_HC_VIS_1_RAM_RD_ARB_STATE_REG_WAIT (7L<<17) +#define BNX2_HC_VIS_1_RAM_WR_ARB_STATE (0x3L<<21) +#define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_NORMAL (0L<<21) +#define BNX2_HC_VIS_1_RAM_WR_ARB_STATE_CLEAR (1L<<21) +#define BNX2_HC_VIS_1_INT_GEN_STATE (1L<<23) +#define BNX2_HC_VIS_1_INT_GEN_STATE_DLE (0L<<23) +#define BNX2_HC_VIS_1_INT_GEN_STATE_NTERRUPT (1L<<23) +#define BNX2_HC_VIS_1_STAT_CHAN_ID (0x7L<<24) +#define BNX2_HC_VIS_1_INT_B (1L<<27) + +#define BNX2_HC_DEBUG_VECT_PEEK 0x00006910 +#define BNX2_HC_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_HC_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_HC_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_HC_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_HC_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_HC_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + + + +/* + * txp_reg definition + * offset: 0x40000 + */ +#define BNX2_TXP_CPU_MODE 0x00045000 +#define BNX2_TXP_CPU_MODE_LOCAL_RST (1L<<0) +#define BNX2_TXP_CPU_MODE_STEP_ENA (1L<<1) +#define BNX2_TXP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) +#define BNX2_TXP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) +#define BNX2_TXP_CPU_MODE_MSG_BIT1 (1L<<6) +#define BNX2_TXP_CPU_MODE_INTERRUPT_ENA (1L<<7) +#define BNX2_TXP_CPU_MODE_SOFT_HALT (1L<<10) +#define BNX2_TXP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) +#define BNX2_TXP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) +#define BNX2_TXP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) +#define BNX2_TXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) + +#define BNX2_TXP_CPU_STATE 0x00045004 +#define BNX2_TXP_CPU_STATE_BREAKPOINT (1L<<0) +#define BNX2_TXP_CPU_STATE_BAD_INST_HALTED (1L<<2) +#define BNX2_TXP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) +#define BNX2_TXP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) +#define BNX2_TXP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) +#define BNX2_TXP_CPU_STATE_BAD_pc_HALTED (1L<<6) +#define BNX2_TXP_CPU_STATE_ALIGN_HALTED (1L<<7) +#define BNX2_TXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) +#define BNX2_TXP_CPU_STATE_SOFT_HALTED (1L<<10) +#define BNX2_TXP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) +#define BNX2_TXP_CPU_STATE_INTERRRUPT (1L<<12) +#define BNX2_TXP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) +#define BNX2_TXP_CPU_STATE_INST_FETCH_STALL (1L<<15) +#define BNX2_TXP_CPU_STATE_BLOCKED_READ (1L<<31) + +#define BNX2_TXP_CPU_EVENT_MASK 0x00045008 +#define BNX2_TXP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) +#define BNX2_TXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) +#define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) +#define BNX2_TXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) +#define BNX2_TXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) +#define BNX2_TXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) +#define BNX2_TXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) +#define BNX2_TXP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) +#define BNX2_TXP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) +#define BNX2_TXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) +#define BNX2_TXP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) + +#define BNX2_TXP_CPU_PROGRAM_COUNTER 0x0004501c +#define BNX2_TXP_CPU_INSTRUCTION 0x00045020 +#define BNX2_TXP_CPU_DATA_ACCESS 0x00045024 +#define BNX2_TXP_CPU_INTERRUPT_ENABLE 0x00045028 +#define BNX2_TXP_CPU_INTERRUPT_VECTOR 0x0004502c +#define BNX2_TXP_CPU_INTERRUPT_SAVED_PC 0x00045030 +#define BNX2_TXP_CPU_HW_BREAKPOINT 0x00045034 +#define BNX2_TXP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) +#define BNX2_TXP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) + +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK 0x00045038 +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_TXP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_TXP_CPU_LAST_BRANCH_ADDR 0x00045048 +#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) +#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) +#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) +#define BNX2_TXP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) + +#define BNX2_TXP_CPU_REG_FILE 0x00045200 +#define BNX2_TXP_FTQ_DATA 0x000453c0 +#define BNX2_TXP_FTQ_CMD 0x000453f8 +#define BNX2_TXP_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_TXP_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_TXP_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_TXP_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_TXP_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_TXP_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_TXP_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_TXP_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_TXP_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_TXP_FTQ_CMD_POP (1L<<30) +#define BNX2_TXP_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_TXP_FTQ_CTL 0x000453fc +#define BNX2_TXP_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_TXP_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_TXP_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_TXP_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_TXP_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_TXP_SCRATCH 0x00060000 + + +/* + * tpat_reg definition + * offset: 0x80000 + */ +#define BNX2_TPAT_CPU_MODE 0x00085000 +#define BNX2_TPAT_CPU_MODE_LOCAL_RST (1L<<0) +#define BNX2_TPAT_CPU_MODE_STEP_ENA (1L<<1) +#define BNX2_TPAT_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) +#define BNX2_TPAT_CPU_MODE_PAGE_0_INST_ENA (1L<<3) +#define BNX2_TPAT_CPU_MODE_MSG_BIT1 (1L<<6) +#define BNX2_TPAT_CPU_MODE_INTERRUPT_ENA (1L<<7) +#define BNX2_TPAT_CPU_MODE_SOFT_HALT (1L<<10) +#define BNX2_TPAT_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) +#define BNX2_TPAT_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) +#define BNX2_TPAT_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) +#define BNX2_TPAT_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) + +#define BNX2_TPAT_CPU_STATE 0x00085004 +#define BNX2_TPAT_CPU_STATE_BREAKPOINT (1L<<0) +#define BNX2_TPAT_CPU_STATE_BAD_INST_HALTED (1L<<2) +#define BNX2_TPAT_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) +#define BNX2_TPAT_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) +#define BNX2_TPAT_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) +#define BNX2_TPAT_CPU_STATE_BAD_pc_HALTED (1L<<6) +#define BNX2_TPAT_CPU_STATE_ALIGN_HALTED (1L<<7) +#define BNX2_TPAT_CPU_STATE_FIO_ABORT_HALTED (1L<<8) +#define BNX2_TPAT_CPU_STATE_SOFT_HALTED (1L<<10) +#define BNX2_TPAT_CPU_STATE_SPAD_UNDERFLOW (1L<<11) +#define BNX2_TPAT_CPU_STATE_INTERRRUPT (1L<<12) +#define BNX2_TPAT_CPU_STATE_DATA_ACCESS_STALL (1L<<14) +#define BNX2_TPAT_CPU_STATE_INST_FETCH_STALL (1L<<15) +#define BNX2_TPAT_CPU_STATE_BLOCKED_READ (1L<<31) + +#define BNX2_TPAT_CPU_EVENT_MASK 0x00085008 +#define BNX2_TPAT_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) +#define BNX2_TPAT_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) +#define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) +#define BNX2_TPAT_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) +#define BNX2_TPAT_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) +#define BNX2_TPAT_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) +#define BNX2_TPAT_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) +#define BNX2_TPAT_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) +#define BNX2_TPAT_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) +#define BNX2_TPAT_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) +#define BNX2_TPAT_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) + +#define BNX2_TPAT_CPU_PROGRAM_COUNTER 0x0008501c +#define BNX2_TPAT_CPU_INSTRUCTION 0x00085020 +#define BNX2_TPAT_CPU_DATA_ACCESS 0x00085024 +#define BNX2_TPAT_CPU_INTERRUPT_ENABLE 0x00085028 +#define BNX2_TPAT_CPU_INTERRUPT_VECTOR 0x0008502c +#define BNX2_TPAT_CPU_INTERRUPT_SAVED_PC 0x00085030 +#define BNX2_TPAT_CPU_HW_BREAKPOINT 0x00085034 +#define BNX2_TPAT_CPU_HW_BREAKPOINT_DISABLE (1L<<0) +#define BNX2_TPAT_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) + +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK 0x00085038 +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_TPAT_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR 0x00085048 +#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) +#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) +#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) +#define BNX2_TPAT_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) + +#define BNX2_TPAT_CPU_REG_FILE 0x00085200 +#define BNX2_TPAT_FTQ_DATA 0x000853c0 +#define BNX2_TPAT_FTQ_CMD 0x000853f8 +#define BNX2_TPAT_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_TPAT_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_TPAT_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_TPAT_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_TPAT_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_TPAT_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_TPAT_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_TPAT_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_TPAT_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_TPAT_FTQ_CMD_POP (1L<<30) +#define BNX2_TPAT_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_TPAT_FTQ_CTL 0x000853fc +#define BNX2_TPAT_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_TPAT_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_TPAT_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_TPAT_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_TPAT_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_TPAT_SCRATCH 0x000a0000 + + +/* + * rxp_reg definition + * offset: 0xc0000 + */ +#define BNX2_RXP_CPU_MODE 0x000c5000 +#define BNX2_RXP_CPU_MODE_LOCAL_RST (1L<<0) +#define BNX2_RXP_CPU_MODE_STEP_ENA (1L<<1) +#define BNX2_RXP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) +#define BNX2_RXP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) +#define BNX2_RXP_CPU_MODE_MSG_BIT1 (1L<<6) +#define BNX2_RXP_CPU_MODE_INTERRUPT_ENA (1L<<7) +#define BNX2_RXP_CPU_MODE_SOFT_HALT (1L<<10) +#define BNX2_RXP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) +#define BNX2_RXP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) +#define BNX2_RXP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) +#define BNX2_RXP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) + +#define BNX2_RXP_CPU_STATE 0x000c5004 +#define BNX2_RXP_CPU_STATE_BREAKPOINT (1L<<0) +#define BNX2_RXP_CPU_STATE_BAD_INST_HALTED (1L<<2) +#define BNX2_RXP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) +#define BNX2_RXP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) +#define BNX2_RXP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) +#define BNX2_RXP_CPU_STATE_BAD_pc_HALTED (1L<<6) +#define BNX2_RXP_CPU_STATE_ALIGN_HALTED (1L<<7) +#define BNX2_RXP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) +#define BNX2_RXP_CPU_STATE_SOFT_HALTED (1L<<10) +#define BNX2_RXP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) +#define BNX2_RXP_CPU_STATE_INTERRRUPT (1L<<12) +#define BNX2_RXP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) +#define BNX2_RXP_CPU_STATE_INST_FETCH_STALL (1L<<15) +#define BNX2_RXP_CPU_STATE_BLOCKED_READ (1L<<31) + +#define BNX2_RXP_CPU_EVENT_MASK 0x000c5008 +#define BNX2_RXP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) +#define BNX2_RXP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) +#define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) +#define BNX2_RXP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) +#define BNX2_RXP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) +#define BNX2_RXP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) +#define BNX2_RXP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) +#define BNX2_RXP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) +#define BNX2_RXP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) +#define BNX2_RXP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) +#define BNX2_RXP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) + +#define BNX2_RXP_CPU_PROGRAM_COUNTER 0x000c501c +#define BNX2_RXP_CPU_INSTRUCTION 0x000c5020 +#define BNX2_RXP_CPU_DATA_ACCESS 0x000c5024 +#define BNX2_RXP_CPU_INTERRUPT_ENABLE 0x000c5028 +#define BNX2_RXP_CPU_INTERRUPT_VECTOR 0x000c502c +#define BNX2_RXP_CPU_INTERRUPT_SAVED_PC 0x000c5030 +#define BNX2_RXP_CPU_HW_BREAKPOINT 0x000c5034 +#define BNX2_RXP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) +#define BNX2_RXP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) + +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK 0x000c5038 +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_RXP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_RXP_CPU_LAST_BRANCH_ADDR 0x000c5048 +#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) +#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) +#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) +#define BNX2_RXP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) + +#define BNX2_RXP_CPU_REG_FILE 0x000c5200 +#define BNX2_RXP_CFTQ_DATA 0x000c5380 +#define BNX2_RXP_CFTQ_CMD 0x000c53b8 +#define BNX2_RXP_CFTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_RXP_CFTQ_CMD_WR_TOP (1L<<10) +#define BNX2_RXP_CFTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_RXP_CFTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_RXP_CFTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_RXP_CFTQ_CMD_RD_DATA (1L<<26) +#define BNX2_RXP_CFTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_RXP_CFTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_RXP_CFTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_RXP_CFTQ_CMD_POP (1L<<30) +#define BNX2_RXP_CFTQ_CMD_BUSY (1L<<31) + +#define BNX2_RXP_CFTQ_CTL 0x000c53bc +#define BNX2_RXP_CFTQ_CTL_INTERVENE (1L<<0) +#define BNX2_RXP_CFTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_RXP_CFTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_RXP_CFTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_RXP_CFTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_RXP_FTQ_DATA 0x000c53c0 +#define BNX2_RXP_FTQ_CMD 0x000c53f8 +#define BNX2_RXP_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_RXP_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_RXP_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_RXP_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_RXP_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_RXP_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_RXP_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_RXP_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_RXP_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_RXP_FTQ_CMD_POP (1L<<30) +#define BNX2_RXP_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_RXP_FTQ_CTL 0x000c53fc +#define BNX2_RXP_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_RXP_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_RXP_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_RXP_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_RXP_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_RXP_SCRATCH 0x000e0000 + + +/* + * com_reg definition + * offset: 0x100000 + */ +#define BNX2_COM_CPU_MODE 0x00105000 +#define BNX2_COM_CPU_MODE_LOCAL_RST (1L<<0) +#define BNX2_COM_CPU_MODE_STEP_ENA (1L<<1) +#define BNX2_COM_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) +#define BNX2_COM_CPU_MODE_PAGE_0_INST_ENA (1L<<3) +#define BNX2_COM_CPU_MODE_MSG_BIT1 (1L<<6) +#define BNX2_COM_CPU_MODE_INTERRUPT_ENA (1L<<7) +#define BNX2_COM_CPU_MODE_SOFT_HALT (1L<<10) +#define BNX2_COM_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) +#define BNX2_COM_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) +#define BNX2_COM_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) +#define BNX2_COM_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) + +#define BNX2_COM_CPU_STATE 0x00105004 +#define BNX2_COM_CPU_STATE_BREAKPOINT (1L<<0) +#define BNX2_COM_CPU_STATE_BAD_INST_HALTED (1L<<2) +#define BNX2_COM_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) +#define BNX2_COM_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) +#define BNX2_COM_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) +#define BNX2_COM_CPU_STATE_BAD_pc_HALTED (1L<<6) +#define BNX2_COM_CPU_STATE_ALIGN_HALTED (1L<<7) +#define BNX2_COM_CPU_STATE_FIO_ABORT_HALTED (1L<<8) +#define BNX2_COM_CPU_STATE_SOFT_HALTED (1L<<10) +#define BNX2_COM_CPU_STATE_SPAD_UNDERFLOW (1L<<11) +#define BNX2_COM_CPU_STATE_INTERRRUPT (1L<<12) +#define BNX2_COM_CPU_STATE_DATA_ACCESS_STALL (1L<<14) +#define BNX2_COM_CPU_STATE_INST_FETCH_STALL (1L<<15) +#define BNX2_COM_CPU_STATE_BLOCKED_READ (1L<<31) + +#define BNX2_COM_CPU_EVENT_MASK 0x00105008 +#define BNX2_COM_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) +#define BNX2_COM_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) +#define BNX2_COM_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) +#define BNX2_COM_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) +#define BNX2_COM_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) +#define BNX2_COM_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) +#define BNX2_COM_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) +#define BNX2_COM_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) +#define BNX2_COM_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) +#define BNX2_COM_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) +#define BNX2_COM_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) + +#define BNX2_COM_CPU_PROGRAM_COUNTER 0x0010501c +#define BNX2_COM_CPU_INSTRUCTION 0x00105020 +#define BNX2_COM_CPU_DATA_ACCESS 0x00105024 +#define BNX2_COM_CPU_INTERRUPT_ENABLE 0x00105028 +#define BNX2_COM_CPU_INTERRUPT_VECTOR 0x0010502c +#define BNX2_COM_CPU_INTERRUPT_SAVED_PC 0x00105030 +#define BNX2_COM_CPU_HW_BREAKPOINT 0x00105034 +#define BNX2_COM_CPU_HW_BREAKPOINT_DISABLE (1L<<0) +#define BNX2_COM_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) + +#define BNX2_COM_CPU_DEBUG_VECT_PEEK 0x00105038 +#define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_COM_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_COM_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_COM_CPU_LAST_BRANCH_ADDR 0x00105048 +#define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) +#define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) +#define BNX2_COM_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) +#define BNX2_COM_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) + +#define BNX2_COM_CPU_REG_FILE 0x00105200 +#define BNX2_COM_COMXQ_FTQ_DATA 0x00105340 +#define BNX2_COM_COMXQ_FTQ_CMD 0x00105378 +#define BNX2_COM_COMXQ_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_COM_COMXQ_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_COM_COMXQ_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_COM_COMXQ_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_COM_COMXQ_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_COM_COMXQ_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_COM_COMXQ_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_COM_COMXQ_FTQ_CMD_POP (1L<<30) +#define BNX2_COM_COMXQ_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_COM_COMXQ_FTQ_CTL 0x0010537c +#define BNX2_COM_COMXQ_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_COM_COMXQ_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_COM_COMXQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_COM_COMXQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_COM_COMXQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_COM_COMTQ_FTQ_DATA 0x00105380 +#define BNX2_COM_COMTQ_FTQ_CMD 0x001053b8 +#define BNX2_COM_COMTQ_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_COM_COMTQ_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_COM_COMTQ_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_COM_COMTQ_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_COM_COMTQ_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_COM_COMTQ_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_COM_COMTQ_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_COM_COMTQ_FTQ_CMD_POP (1L<<30) +#define BNX2_COM_COMTQ_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_COM_COMTQ_FTQ_CTL 0x001053bc +#define BNX2_COM_COMTQ_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_COM_COMTQ_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_COM_COMTQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_COM_COMTQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_COM_COMTQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_COM_COMQ_FTQ_DATA 0x001053c0 +#define BNX2_COM_COMQ_FTQ_CMD 0x001053f8 +#define BNX2_COM_COMQ_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_COM_COMQ_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_COM_COMQ_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_COM_COMQ_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_COM_COMQ_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_COM_COMQ_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_COM_COMQ_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_COM_COMQ_FTQ_CMD_POP (1L<<30) +#define BNX2_COM_COMQ_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_COM_COMQ_FTQ_CTL 0x001053fc +#define BNX2_COM_COMQ_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_COM_COMQ_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_COM_COMQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_COM_COMQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_COM_COMQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_COM_SCRATCH 0x00120000 + + +/* + * cp_reg definition + * offset: 0x180000 + */ +#define BNX2_CP_CPU_MODE 0x00185000 +#define BNX2_CP_CPU_MODE_LOCAL_RST (1L<<0) +#define BNX2_CP_CPU_MODE_STEP_ENA (1L<<1) +#define BNX2_CP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) +#define BNX2_CP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) +#define BNX2_CP_CPU_MODE_MSG_BIT1 (1L<<6) +#define BNX2_CP_CPU_MODE_INTERRUPT_ENA (1L<<7) +#define BNX2_CP_CPU_MODE_SOFT_HALT (1L<<10) +#define BNX2_CP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) +#define BNX2_CP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) +#define BNX2_CP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) +#define BNX2_CP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) + +#define BNX2_CP_CPU_STATE 0x00185004 +#define BNX2_CP_CPU_STATE_BREAKPOINT (1L<<0) +#define BNX2_CP_CPU_STATE_BAD_INST_HALTED (1L<<2) +#define BNX2_CP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) +#define BNX2_CP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) +#define BNX2_CP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) +#define BNX2_CP_CPU_STATE_BAD_pc_HALTED (1L<<6) +#define BNX2_CP_CPU_STATE_ALIGN_HALTED (1L<<7) +#define BNX2_CP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) +#define BNX2_CP_CPU_STATE_SOFT_HALTED (1L<<10) +#define BNX2_CP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) +#define BNX2_CP_CPU_STATE_INTERRRUPT (1L<<12) +#define BNX2_CP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) +#define BNX2_CP_CPU_STATE_INST_FETCH_STALL (1L<<15) +#define BNX2_CP_CPU_STATE_BLOCKED_READ (1L<<31) + +#define BNX2_CP_CPU_EVENT_MASK 0x00185008 +#define BNX2_CP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) +#define BNX2_CP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) +#define BNX2_CP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) +#define BNX2_CP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) +#define BNX2_CP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) +#define BNX2_CP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) +#define BNX2_CP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) +#define BNX2_CP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) +#define BNX2_CP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) +#define BNX2_CP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) +#define BNX2_CP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) + +#define BNX2_CP_CPU_PROGRAM_COUNTER 0x0018501c +#define BNX2_CP_CPU_INSTRUCTION 0x00185020 +#define BNX2_CP_CPU_DATA_ACCESS 0x00185024 +#define BNX2_CP_CPU_INTERRUPT_ENABLE 0x00185028 +#define BNX2_CP_CPU_INTERRUPT_VECTOR 0x0018502c +#define BNX2_CP_CPU_INTERRUPT_SAVED_PC 0x00185030 +#define BNX2_CP_CPU_HW_BREAKPOINT 0x00185034 +#define BNX2_CP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) +#define BNX2_CP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) + +#define BNX2_CP_CPU_DEBUG_VECT_PEEK 0x00185038 +#define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_CP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_CP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_CP_CPU_LAST_BRANCH_ADDR 0x00185048 +#define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) +#define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) +#define BNX2_CP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) +#define BNX2_CP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) + +#define BNX2_CP_CPU_REG_FILE 0x00185200 +#define BNX2_CP_CPQ_FTQ_DATA 0x001853c0 +#define BNX2_CP_CPQ_FTQ_CMD 0x001853f8 +#define BNX2_CP_CPQ_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_CP_CPQ_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_CP_CPQ_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_CP_CPQ_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_CP_CPQ_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_CP_CPQ_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_CP_CPQ_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_CP_CPQ_FTQ_CMD_POP (1L<<30) +#define BNX2_CP_CPQ_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_CP_CPQ_FTQ_CTL 0x001853fc +#define BNX2_CP_CPQ_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_CP_CPQ_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_CP_CPQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_CP_CPQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_CP_CPQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_CP_SCRATCH 0x001a0000 + + +/* + * mcp_reg definition + * offset: 0x140000 + */ +#define BNX2_MCP_CPU_MODE 0x00145000 +#define BNX2_MCP_CPU_MODE_LOCAL_RST (1L<<0) +#define BNX2_MCP_CPU_MODE_STEP_ENA (1L<<1) +#define BNX2_MCP_CPU_MODE_PAGE_0_DATA_ENA (1L<<2) +#define BNX2_MCP_CPU_MODE_PAGE_0_INST_ENA (1L<<3) +#define BNX2_MCP_CPU_MODE_MSG_BIT1 (1L<<6) +#define BNX2_MCP_CPU_MODE_INTERRUPT_ENA (1L<<7) +#define BNX2_MCP_CPU_MODE_SOFT_HALT (1L<<10) +#define BNX2_MCP_CPU_MODE_BAD_DATA_HALT_ENA (1L<<11) +#define BNX2_MCP_CPU_MODE_BAD_INST_HALT_ENA (1L<<12) +#define BNX2_MCP_CPU_MODE_FIO_ABORT_HALT_ENA (1L<<13) +#define BNX2_MCP_CPU_MODE_SPAD_UNDERFLOW_HALT_ENA (1L<<15) + +#define BNX2_MCP_CPU_STATE 0x00145004 +#define BNX2_MCP_CPU_STATE_BREAKPOINT (1L<<0) +#define BNX2_MCP_CPU_STATE_BAD_INST_HALTED (1L<<2) +#define BNX2_MCP_CPU_STATE_PAGE_0_DATA_HALTED (1L<<3) +#define BNX2_MCP_CPU_STATE_PAGE_0_INST_HALTED (1L<<4) +#define BNX2_MCP_CPU_STATE_BAD_DATA_ADDR_HALTED (1L<<5) +#define BNX2_MCP_CPU_STATE_BAD_pc_HALTED (1L<<6) +#define BNX2_MCP_CPU_STATE_ALIGN_HALTED (1L<<7) +#define BNX2_MCP_CPU_STATE_FIO_ABORT_HALTED (1L<<8) +#define BNX2_MCP_CPU_STATE_SOFT_HALTED (1L<<10) +#define BNX2_MCP_CPU_STATE_SPAD_UNDERFLOW (1L<<11) +#define BNX2_MCP_CPU_STATE_INTERRRUPT (1L<<12) +#define BNX2_MCP_CPU_STATE_DATA_ACCESS_STALL (1L<<14) +#define BNX2_MCP_CPU_STATE_INST_FETCH_STALL (1L<<15) +#define BNX2_MCP_CPU_STATE_BLOCKED_READ (1L<<31) + +#define BNX2_MCP_CPU_EVENT_MASK 0x00145008 +#define BNX2_MCP_CPU_EVENT_MASK_BREAKPOINT_MASK (1L<<0) +#define BNX2_MCP_CPU_EVENT_MASK_BAD_INST_HALTED_MASK (1L<<2) +#define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_DATA_HALTED_MASK (1L<<3) +#define BNX2_MCP_CPU_EVENT_MASK_PAGE_0_INST_HALTED_MASK (1L<<4) +#define BNX2_MCP_CPU_EVENT_MASK_BAD_DATA_ADDR_HALTED_MASK (1L<<5) +#define BNX2_MCP_CPU_EVENT_MASK_BAD_PC_HALTED_MASK (1L<<6) +#define BNX2_MCP_CPU_EVENT_MASK_ALIGN_HALTED_MASK (1L<<7) +#define BNX2_MCP_CPU_EVENT_MASK_FIO_ABORT_MASK (1L<<8) +#define BNX2_MCP_CPU_EVENT_MASK_SOFT_HALTED_MASK (1L<<10) +#define BNX2_MCP_CPU_EVENT_MASK_SPAD_UNDERFLOW_MASK (1L<<11) +#define BNX2_MCP_CPU_EVENT_MASK_INTERRUPT_MASK (1L<<12) + +#define BNX2_MCP_CPU_PROGRAM_COUNTER 0x0014501c +#define BNX2_MCP_CPU_INSTRUCTION 0x00145020 +#define BNX2_MCP_CPU_DATA_ACCESS 0x00145024 +#define BNX2_MCP_CPU_INTERRUPT_ENABLE 0x00145028 +#define BNX2_MCP_CPU_INTERRUPT_VECTOR 0x0014502c +#define BNX2_MCP_CPU_INTERRUPT_SAVED_PC 0x00145030 +#define BNX2_MCP_CPU_HW_BREAKPOINT 0x00145034 +#define BNX2_MCP_CPU_HW_BREAKPOINT_DISABLE (1L<<0) +#define BNX2_MCP_CPU_HW_BREAKPOINT_ADDRESS (0x3fffffffL<<2) + +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK 0x00145038 +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_VALUE (0x7ffL<<0) +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_PEEK_EN (1L<<11) +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_1_SEL (0xfL<<12) +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_VALUE (0x7ffL<<16) +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_PEEK_EN (1L<<27) +#define BNX2_MCP_CPU_DEBUG_VECT_PEEK_2_SEL (0xfL<<28) + +#define BNX2_MCP_CPU_LAST_BRANCH_ADDR 0x00145048 +#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE (1L<<1) +#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_JUMP (0L<<1) +#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_TYPE_BRANCH (1L<<1) +#define BNX2_MCP_CPU_LAST_BRANCH_ADDR_LBA (0x3fffffffL<<2) + +#define BNX2_MCP_CPU_REG_FILE 0x00145200 +#define BNX2_MCP_MCPQ_FTQ_DATA 0x001453c0 +#define BNX2_MCP_MCPQ_FTQ_CMD 0x001453f8 +#define BNX2_MCP_MCPQ_FTQ_CMD_OFFSET (0x3ffL<<0) +#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP (1L<<10) +#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_0 (0L<<10) +#define BNX2_MCP_MCPQ_FTQ_CMD_WR_TOP_1 (1L<<10) +#define BNX2_MCP_MCPQ_FTQ_CMD_SFT_RESET (1L<<25) +#define BNX2_MCP_MCPQ_FTQ_CMD_RD_DATA (1L<<26) +#define BNX2_MCP_MCPQ_FTQ_CMD_ADD_INTERVEN (1L<<27) +#define BNX2_MCP_MCPQ_FTQ_CMD_ADD_DATA (1L<<28) +#define BNX2_MCP_MCPQ_FTQ_CMD_INTERVENE_CLR (1L<<29) +#define BNX2_MCP_MCPQ_FTQ_CMD_POP (1L<<30) +#define BNX2_MCP_MCPQ_FTQ_CMD_BUSY (1L<<31) + +#define BNX2_MCP_MCPQ_FTQ_CTL 0x001453fc +#define BNX2_MCP_MCPQ_FTQ_CTL_INTERVENE (1L<<0) +#define BNX2_MCP_MCPQ_FTQ_CTL_OVERFLOW (1L<<1) +#define BNX2_MCP_MCPQ_FTQ_CTL_FORCE_INTERVENE (1L<<2) +#define BNX2_MCP_MCPQ_FTQ_CTL_MAX_DEPTH (0x3ffL<<12) +#define BNX2_MCP_MCPQ_FTQ_CTL_CUR_DEPTH (0x3ffL<<22) + +#define BNX2_MCP_ROM 0x00150000 +#define BNX2_MCP_SCRATCH 0x00160000 + + +#define NUM_MC_HASH_REGISTERS 8 + + +/* PHY_ID1: bits 31-16; PHY_ID2: bits 15-0. */ +#define PHY_BCM5706_PHY_ID 0x00206160 + +#define PHY_ID(id) ((id) & 0xfffffff0) +#define PHY_REV_ID(id) ((id) & 0xf) + +#define MIN_ETHERNET_PACKET_SIZE 60 +#define MAX_ETHERNET_PACKET_SIZE 1514 +#define MAX_ETHERNET_JUMBO_PACKET_SIZE 9014 + +#define RX_COPY_THRESH 92 + +#define DMA_READ_CHANS 5 +#define DMA_WRITE_CHANS 3 + +#define BCM_PAGE_BITS 12 +#define BCM_PAGE_SIZE (1 << BCM_PAGE_BITS) + +#define TX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct tx_bd)) +#define MAX_TX_DESC_CNT (TX_DESC_CNT - 1) + +#define RX_DESC_CNT (BCM_PAGE_SIZE / sizeof(struct rx_bd)) +#define MAX_RX_DESC_CNT (RX_DESC_CNT - 1) + +#define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) == \ + (MAX_TX_DESC_CNT - 1)) ? \ + (x) + 2 : (x) + 1 + +#define TX_RING_IDX(x) ((x) & MAX_TX_DESC_CNT) + +#define NEXT_RX_BD(x) (((x) & (MAX_RX_DESC_CNT - 1)) == \ + (MAX_RX_DESC_CNT - 1)) ? \ + (x) + 2 : (x) + 1 + +#define RX_RING_IDX(x) ((x) & MAX_RX_DESC_CNT) + + +/* Context size. */ +#define CTX_SHIFT 7 +#define CTX_SIZE (1 << CTX_SHIFT) +#define CTX_MASK (CTX_SIZE - 1) +#define GET_CID_ADDR(_cid) ((_cid) << CTX_SHIFT) +#define GET_CID(_cid_addr) ((_cid_addr) >> CTX_SHIFT) + +#define PHY_CTX_SHIFT 6 +#define PHY_CTX_SIZE (1 << PHY_CTX_SHIFT) +#define PHY_CTX_MASK (PHY_CTX_SIZE - 1) +#define GET_PCID_ADDR(_pcid) ((_pcid) << PHY_CTX_SHIFT) +#define GET_PCID(_pcid_addr) ((_pcid_addr) >> PHY_CTX_SHIFT) + +#define MB_KERNEL_CTX_SHIFT 8 +#define MB_KERNEL_CTX_SIZE (1 << MB_KERNEL_CTX_SHIFT) +#define MB_KERNEL_CTX_MASK (MB_KERNEL_CTX_SIZE - 1) +#define MB_GET_CID_ADDR(_cid) (0x10000 + ((_cid) << MB_KERNEL_CTX_SHIFT)) + +#define MAX_CID_CNT 0x4000 +#define MAX_CID_ADDR (GET_CID_ADDR(MAX_CID_CNT)) +#define INVALID_CID_ADDR 0xffffffff + +#define TX_CID 16 +#define RX_CID 0 + +#define MB_TX_CID_ADDR MB_GET_CID_ADDR(TX_CID) +#define MB_RX_CID_ADDR MB_GET_CID_ADDR(RX_CID) + +struct sw_bd { + struct sk_buff *skb; + DECLARE_PCI_UNMAP_ADDR(mapping) +}; + +/* Buffered flash (Atmel: AT45DB011B) specific information */ +#define SEEPROM_PAGE_BITS 2 +#define SEEPROM_PHY_PAGE_SIZE (1 << SEEPROM_PAGE_BITS) +#define SEEPROM_BYTE_ADDR_MASK (SEEPROM_PHY_PAGE_SIZE-1) +#define SEEPROM_PAGE_SIZE 4 +#define SEEPROM_TOTAL_SIZE 65536 + +#define BUFFERED_FLASH_PAGE_BITS 9 +#define BUFFERED_FLASH_PHY_PAGE_SIZE (1 << BUFFERED_FLASH_PAGE_BITS) +#define BUFFERED_FLASH_BYTE_ADDR_MASK (BUFFERED_FLASH_PHY_PAGE_SIZE-1) +#define BUFFERED_FLASH_PAGE_SIZE 264 +#define BUFFERED_FLASH_TOTAL_SIZE 131072 + +#define SAIFUN_FLASH_PAGE_BITS 8 +#define SAIFUN_FLASH_PHY_PAGE_SIZE (1 << SAIFUN_FLASH_PAGE_BITS) +#define SAIFUN_FLASH_BYTE_ADDR_MASK (SAIFUN_FLASH_PHY_PAGE_SIZE-1) +#define SAIFUN_FLASH_PAGE_SIZE 256 +#define SAIFUN_FLASH_BASE_TOTAL_SIZE 65536 + +#define NVRAM_TIMEOUT_COUNT 30000 + + +#define FLASH_STRAP_MASK (BNX2_NVM_CFG1_FLASH_MODE | \ + BNX2_NVM_CFG1_BUFFER_MODE | \ + BNX2_NVM_CFG1_PROTECT_MODE | \ + BNX2_NVM_CFG1_FLASH_SIZE) + +struct flash_spec { + u32 strapping; + u32 config1; + u32 config2; + u32 config3; + u32 write1; + u32 buffered; + u32 page_bits; + u32 page_size; + u32 addr_mask; + u32 total_size; + u8 *name; +}; + +struct bnx2 { + /* Fields used in the tx and intr/napi performance paths are grouped */ + /* together in the beginning of the structure. */ + void __iomem *regview; + + struct net_device *dev; + struct pci_dev *pdev; + + atomic_t intr_sem; + + struct status_block *status_blk; + u32 last_status_idx; + + atomic_t tx_avail_bd; + struct tx_bd *tx_desc_ring; + struct sw_bd *tx_buf_ring; + u32 tx_prod_bseq; + u16 tx_prod; + u16 tx_cons; + +#ifdef BCM_VLAN + struct vlan_group *vlgrp; +#endif + + u32 rx_offset; + u32 rx_buf_use_size; /* useable size */ + u32 rx_buf_size; /* with alignment */ + struct rx_bd *rx_desc_ring; + struct sw_bd *rx_buf_ring; + u32 rx_prod_bseq; + u16 rx_prod; + u16 rx_cons; + + u32 rx_csum; + + /* Only used to synchronize netif_stop_queue/wake_queue when tx */ + /* ring is full */ + spinlock_t tx_lock; + + /* End of fileds used in the performance code paths. */ + + char *name; + + int timer_interval; + struct timer_list timer; + struct work_struct reset_task; + + /* Used to synchronize phy accesses. */ + spinlock_t phy_lock; + + u32 flags; +#define PCIX_FLAG 1 +#define PCI_32BIT_FLAG 2 +#define ONE_TDMA_FLAG 4 /* no longer used */ +#define NO_WOL_FLAG 8 +#define USING_DAC_FLAG 0x10 +#define USING_MSI_FLAG 0x20 + + u32 phy_flags; +#define PHY_SERDES_FLAG 1 +#define PHY_CRC_FIX_FLAG 2 +#define PHY_PARALLEL_DETECT_FLAG 4 +#define PHY_INT_MODE_MASK_FLAG 0x300 +#define PHY_INT_MODE_AUTO_POLLING_FLAG 0x100 +#define PHY_INT_MODE_LINK_READY_FLAG 0x200 + + u32 chip_id; + /* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */ +#define CHIP_NUM(bp) (((bp)->chip_id) & 0xffff0000) +#define CHIP_NUM_5706 0x57060000 + +#define CHIP_REV(bp) (((bp)->chip_id) & 0x0000f000) +#define CHIP_REV_Ax 0x00000000 +#define CHIP_REV_Bx 0x00001000 +#define CHIP_REV_Cx 0x00002000 + +#define CHIP_METAL(bp) (((bp)->chip_id) & 0x00000ff0) +#define CHIP_BONDING(bp) (((bp)->chip_id) & 0x0000000f) + +#define CHIP_ID(bp) (((bp)->chip_id) & 0xfffffff0) +#define CHIP_ID_5706_A0 0x57060000 +#define CHIP_ID_5706_A1 0x57060010 + +#define CHIP_BOND_ID(bp) (((bp)->chip_id) & 0xf) + +/* A serdes chip will have the first bit of the bond id set. */ +#define CHIP_BOND_ID_SERDES_BIT 0x01 + + u32 phy_addr; + u32 phy_id; + + u16 bus_speed_mhz; + u8 wol; + + u8 fw_timed_out; + + u16 fw_wr_seq; + u16 fw_drv_pulse_wr_seq; + + int tx_ring_size; + dma_addr_t tx_desc_mapping; + + + int rx_ring_size; + dma_addr_t rx_desc_mapping; + + u16 tx_quick_cons_trip; + u16 tx_quick_cons_trip_int; + u16 rx_quick_cons_trip; + u16 rx_quick_cons_trip_int; + u16 comp_prod_trip; + u16 comp_prod_trip_int; + u16 tx_ticks; + u16 tx_ticks_int; + u16 com_ticks; + u16 com_ticks_int; + u16 cmd_ticks; + u16 cmd_ticks_int; + u16 rx_ticks; + u16 rx_ticks_int; + + u32 stats_ticks; + + dma_addr_t status_blk_mapping; + + struct statistics_block *stats_blk; + dma_addr_t stats_blk_mapping; + + u32 rx_mode; + + u16 req_line_speed; + u8 req_duplex; + + u8 link_up; + + u16 line_speed; + u8 duplex; + u8 flow_ctrl; /* actual flow ctrl settings */ + /* may be different from */ + /* req_flow_ctrl if autoneg */ +#define FLOW_CTRL_TX 1 +#define FLOW_CTRL_RX 2 + + u32 advertising; + + u8 req_flow_ctrl; /* flow ctrl advertisement */ + /* settings or forced */ + /* settings */ + u8 autoneg; +#define AUTONEG_SPEED 1 +#define AUTONEG_FLOW_CTRL 2 + + u8 loopback; +#define MAC_LOOPBACK 1 +#define PHY_LOOPBACK 2 + + u8 serdes_an_pending; +#define SERDES_AN_TIMEOUT (2 * HZ) + + u8 mac_addr[8]; + + u32 fw_ver; + + int pm_cap; + int pcix_cap; + + struct net_device_stats net_stats; + + struct flash_spec *flash_info; +}; + +static u32 bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset); +static void bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val); + +#define REG_RD(bp, offset) \ + readl(bp->regview + offset) + +#define REG_WR(bp, offset, val) \ + writel(val, bp->regview + offset) + +#define REG_WR16(bp, offset, val) \ + writew(val, bp->regview + offset) + +#define REG_RD_IND(bp, offset) \ + bnx2_reg_rd_ind(bp, offset) + +#define REG_WR_IND(bp, offset, val) \ + bnx2_reg_wr_ind(bp, offset, val) + +/* Indirect context access. Unlike the MBQ_WR, these macros will not + * trigger a chip event. */ +static void bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val); + +#define CTX_WR(bp, cid_addr, offset, val) \ + bnx2_ctx_wr(bp, cid_addr, offset, val) + +struct cpu_reg { + u32 mode; + u32 mode_value_halt; + u32 mode_value_sstep; + + u32 state; + u32 state_value_clear; + + u32 gpr0; + u32 evmask; + u32 pc; + u32 inst; + u32 bp; + + u32 spad_base; + + u32 mips_view_base; +}; + +struct fw_info { + u32 ver_major; + u32 ver_minor; + u32 ver_fix; + + u32 start_addr; + + /* Text section. */ + u32 text_addr; + u32 text_len; + u32 text_index; + u32 *text; + + /* Data section. */ + u32 data_addr; + u32 data_len; + u32 data_index; + u32 *data; + + /* SBSS section. */ + u32 sbss_addr; + u32 sbss_len; + u32 sbss_index; + u32 *sbss; + + /* BSS section. */ + u32 bss_addr; + u32 bss_len; + u32 bss_index; + u32 *bss; + + /* Read-only section. */ + u32 rodata_addr; + u32 rodata_len; + u32 rodata_index; + u32 *rodata; +}; + +#define RV2P_PROC1 0 +#define RV2P_PROC2 1 + + +/* This value (in milliseconds) determines the frequency of the driver + * issuing the PULSE message code. The firmware monitors this periodic + * pulse to determine when to switch to an OS-absent mode. */ +#define DRV_PULSE_PERIOD_MS 250 + +/* This value (in milliseconds) determines how long the driver should + * wait for an acknowledgement from the firmware before timing out. Once + * the firmware has timed out, the driver will assume there is no firmware + * running and there won't be any firmware-driver synchronization during a + * driver reset. */ +#define FW_ACK_TIME_OUT_MS 50 + + +#define BNX2_DRV_RESET_SIGNATURE 0x00000000 +#define BNX2_DRV_RESET_SIGNATURE_MAGIC 0x4841564b /* HAVK */ +//#define DRV_RESET_SIGNATURE_MAGIC 0x47495352 /* RSIG */ + +#define BNX2_DRV_MB 0x00000004 +#define BNX2_DRV_MSG_CODE 0xff000000 +#define BNX2_DRV_MSG_CODE_RESET 0x01000000 +#define BNX2_DRV_MSG_CODE_UNLOAD 0x02000000 +#define BNX2_DRV_MSG_CODE_SHUTDOWN 0x03000000 +#define BNX2_DRV_MSG_CODE_SUSPEND_WOL 0x04000000 +#define BNX2_DRV_MSG_CODE_FW_TIMEOUT 0x05000000 +#define BNX2_DRV_MSG_CODE_PULSE 0x06000000 +#define BNX2_DRV_MSG_CODE_DIAG 0x07000000 +#define BNX2_DRV_MSG_CODE_SUSPEND_NO_WOL 0x09000000 + +#define BNX2_DRV_MSG_DATA 0x00ff0000 +#define BNX2_DRV_MSG_DATA_WAIT0 0x00010000 +#define BNX2_DRV_MSG_DATA_WAIT1 0x00020000 +#define BNX2_DRV_MSG_DATA_WAIT2 0x00030000 +#define BNX2_DRV_MSG_DATA_WAIT3 0x00040000 + +#define BNX2_DRV_MSG_SEQ 0x0000ffff + +#define BNX2_FW_MB 0x00000008 +#define BNX2_FW_MSG_ACK 0x0000ffff +#define BNX2_FW_MSG_STATUS_MASK 0x00ff0000 +#define BNX2_FW_MSG_STATUS_OK 0x00000000 +#define BNX2_FW_MSG_STATUS_FAILURE 0x00ff0000 + +#define BNX2_LINK_STATUS 0x0000000c + +#define BNX2_DRV_PULSE_MB 0x00000010 +#define BNX2_DRV_PULSE_SEQ_MASK 0x0000ffff + +/* Indicate to the firmware not to go into the + * OS absent when it is not getting driver pulse. + * This is used for debugging. */ +#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE 0x00010000 + +#define BNX2_DEV_INFO_SIGNATURE 0x00000020 +#define BNX2_DEV_INFO_SIGNATURE_MAGIC 0x44564900 +#define BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK 0xffffff00 +#define BNX2_DEV_INFO_FEATURE_CFG_VALID 0x01 +#define BNX2_DEV_INFO_SECONDARY_PORT 0x80 +#define BNX2_DEV_INFO_DRV_ALWAYS_ALIVE 0x40 + +#define BNX2_SHARED_HW_CFG_PART_NUM 0x00000024 + +#define BNX2_SHARED_HW_CFG_POWER_DISSIPATED 0x00000034 +#define BNX2_SHARED_HW_CFG_POWER_STATE_D3_MASK 0xff000000 +#define BNX2_SHARED_HW_CFG_POWER_STATE_D2_MASK 0xff0000 +#define BNX2_SHARED_HW_CFG_POWER_STATE_D1_MASK 0xff00 +#define BNX2_SHARED_HW_CFG_POWER_STATE_D0_MASK 0xff + +#define BNX2_SHARED_HW_CFG POWER_CONSUMED 0x00000038 +#define BNX2_SHARED_HW_CFG_CONFIG 0x0000003c +#define BNX2_SHARED_HW_CFG_DESIGN_NIC 0 +#define BNX2_SHARED_HW_CFG_DESIGN_LOM 0x1 +#define BNX2_SHARED_HW_CFG_PHY_COPPER 0 +#define BNX2_SHARED_HW_CFG_PHY_FIBER 0x2 +#define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS 8 +#define BNX2_SHARED_HW_CFG_LED_MODE_MASK 0x300 +#define BNX2_SHARED_HW_CFG_LED_MODE_MAC 0 +#define BNX2_SHARED_HW_CFG_LED_MODE_GPHY1 0x100 +#define BNX2_SHARED_HW_CFG_LED_MODE_GPHY2 0x200 + +#define BNX2_DEV_INFO_BC_REV 0x0000004c + +#define BNX2_PORT_HW_CFG_MAC_UPPER 0x00000050 +#define BNX2_PORT_HW_CFG_UPPERMAC_MASK 0xffff + +#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054 +#define BNX2_PORT_HW_CFG_CONFIG 0x00000058 + +#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068 +#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c +#define BNX2_PORT_HW_CFG_IMD_MAC_B_UPPER 0x00000070 +#define BNX2_PORT_HW_CFG_IMD_MAC_B_LOWER 0x00000074 +#define BNX2_PORT_HW_CFG_ISCSI_MAC_UPPER 0x00000078 +#define BNX2_PORT_HW_CFG_ISCSI_MAC_LOWER 0x0000007c + +#define BNX2_DEV_INFO_PER_PORT_HW_CONFIG2 0x000000b4 + +#define BNX2_DEV_INFO_FORMAT_REV 0x000000c4 +#define BNX2_DEV_INFO_FORMAT_REV_MASK 0xff000000 +#define BNX2_DEV_INFO_FORMAT_REV_ID ('A' << 24) + +#define BNX2_SHARED_FEATURE 0x000000c8 +#define BNX2_SHARED_FEATURE_MASK 0xffffffff + +#define BNX2_PORT_FEATURE 0x000000d8 +#define BNX2_PORT2_FEATURE 0x00000014c +#define BNX2_PORT_FEATURE_WOL_ENABLED 0x01000000 +#define BNX2_PORT_FEATURE_MBA_ENABLED 0x02000000 +#define BNX2_PORT_FEATURE_ASF_ENABLED 0x04000000 +#define BNX2_PORT_FEATURE_IMD_ENABLED 0x08000000 +#define BNX2_PORT_FEATURE_BAR1_SIZE_MASK 0xf +#define BNX2_PORT_FEATURE_BAR1_SIZE_DISABLED 0x0 +#define BNX2_PORT_FEATURE_BAR1_SIZE_64K 0x1 +#define BNX2_PORT_FEATURE_BAR1_SIZE_128K 0x2 +#define BNX2_PORT_FEATURE_BAR1_SIZE_256K 0x3 +#define BNX2_PORT_FEATURE_BAR1_SIZE_512K 0x4 +#define BNX2_PORT_FEATURE_BAR1_SIZE_1M 0x5 +#define BNX2_PORT_FEATURE_BAR1_SIZE_2M 0x6 +#define BNX2_PORT_FEATURE_BAR1_SIZE_4M 0x7 +#define BNX2_PORT_FEATURE_BAR1_SIZE_8M 0x8 +#define BNX2_PORT_FEATURE_BAR1_SIZE_16M 0x9 +#define BNX2_PORT_FEATURE_BAR1_SIZE_32M 0xa +#define BNX2_PORT_FEATURE_BAR1_SIZE_64M 0xb +#define BNX2_PORT_FEATURE_BAR1_SIZE_128M 0xc +#define BNX2_PORT_FEATURE_BAR1_SIZE_256M 0xd +#define BNX2_PORT_FEATURE_BAR1_SIZE_512M 0xe +#define BNX2_PORT_FEATURE_BAR1_SIZE_1G 0xf + +#define BNX2_PORT_FEATURE_WOL 0xdc +#define BNX2_PORT2_FEATURE_WOL 0x150 +#define BNX2_PORT_FEATURE_WOL_DEFAULT_SHIFT_BITS 4 +#define BNX2_PORT_FEATURE_WOL_DEFAULT_MASK 0x30 +#define BNX2_PORT_FEATURE_WOL_DEFAULT_DISABLE 0 +#define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC 0x10 +#define BNX2_PORT_FEATURE_WOL_DEFAULT_ACPI 0x20 +#define BNX2_PORT_FEATURE_WOL_DEFAULT_MAGIC_AND_ACPI 0x30 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_MASK 0xf +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_AUTONEG 0 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10HALF 1 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_10FULL 2 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100HALF 3 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_100FULL 4 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000HALF 5 +#define BNX2_PORT_FEATURE_WOL_LINK_SPEED_1000FULL 6 +#define BNX2_PORT_FEATURE_WOL_AUTONEG_ADVERTISE_1000 0x40 +#define BNX2_PORT_FEATURE_WOL_RESERVED_PAUSE_CAP 0x400 +#define BNX2_PORT_FEATURE_WOL_RESERVED_ASYM_PAUSE_CAP 0x800 + +#define BNX2_PORT_FEATURE_MBA 0xe0 +#define BNX2_PORT2_FEATURE_MBA 0x154 +#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_SHIFT_BITS 0 +#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_MASK 0x3 +#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_PXE 0 +#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_RPL 1 +#define BNX2_PORT_FEATURE_MBA_BOOT_AGENT_TYPE_BOOTP 2 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_SHIFT_BITS 2 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_MASK 0x3c +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_AUTONEG 0 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10HALF 0x4 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_10FULL 0x8 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100HALF 0xc +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_100FULL 0x10 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000HALF 0x14 +#define BNX2_PORT_FEATURE_MBA_LINK_SPEED_1000FULL 0x18 +#define BNX2_PORT_FEATURE_MBA_SETUP_PROMPT_ENABLE 0x40 +#define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_S 0 +#define BNX2_PORT_FEATURE_MBA_HOTKEY_CTRL_B 0x80 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_SHIFT_BITS 8 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_MASK 0xff00 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_DISABLED 0 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1K 0x100 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2K 0x200 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4K 0x300 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8K 0x400 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16K 0x500 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_32K 0x600 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_64K 0x700 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_128K 0x800 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_256K 0x900 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_512K 0xa00 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_1M 0xb00 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_2M 0xc00 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_4M 0xd00 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_8M 0xe00 +#define BNX2_PORT_FEATURE_MBA_EXP_ROM_SIZE_16M 0xf00 +#define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_SHIFT_BITS 16 +#define BNX2_PORT_FEATURE_MBA_MSG_TIMEOUT_MASK 0xf0000 +#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_SHIFT_BITS 20 +#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_MASK 0x300000 +#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_AUTO 0 +#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_BBS 0x100000 +#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT18H 0x200000 +#define BNX2_PORT_FEATURE_MBA_BIOS_BOOTSTRAP_INT19H 0x300000 + +#define BNX2_PORT_FEATURE_IMD 0xe4 +#define BNX2_PORT2_FEATURE_IMD 0x158 +#define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_DEFAULT 0 +#define BNX2_PORT_FEATURE_IMD_LINK_OVERRIDE_ENABLE 1 + +#define BNX2_PORT_FEATURE_VLAN 0xe8 +#define BNX2_PORT2_FEATURE_VLAN 0x15c +#define BNX2_PORT_FEATURE_MBA_VLAN_TAG_MASK 0xffff +#define BNX2_PORT_FEATURE_MBA_VLAN_ENABLE 0x10000 + +#define BNX2_BC_STATE_RESET_TYPE 0x000001c0 +#define BNX2_BC_STATE_RESET_TYPE_SIG 0x00005254 +#define BNX2_BC_STATE_RESET_TYPE_SIG_MASK 0x0000ffff +#define BNX2_BC_STATE_RESET_TYPE_NONE (BNX2_BC_STATE_RESET_TYPE_SIG | \ + 0x00010000) +#define BNX2_BC_STATE_RESET_TYPE_PCI (BNX2_BC_STATE_RESET_TYPE_SIG | \ + 0x00020000) +#define BNX2_BC_STATE_RESET_TYPE_VAUX (BNX2_BC_STATE_RESET_TYPE_SIG | \ + 0x00030000) +#define BNX2_BC_STATE_RESET_TYPE_DRV_MASK DRV_MSG_CODE +#define BNX2_BC_STATE_RESET_TYPE_DRV_RESET (BNX2_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_RESET) +#define BNX2_BC_STATE_RESET_TYPE_DRV_UNLOAD (BNX2_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_UNLOAD) +#define BNX2_BC_STATE_RESET_TYPE_DRV_SHUTDOWN (BNX2_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_SHUTDOWN) +#define BNX2_BC_STATE_RESET_TYPE_DRV_WOL (BNX2_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_WOL) +#define BNX2_BC_STATE_RESET_TYPE_DRV_DIAG (BNX2_BC_STATE_RESET_TYPE_SIG | \ + DRV_MSG_CODE_DIAG) +#define BNX2_BC_STATE_RESET_TYPE_VALUE(msg) (BNX2_BC_STATE_RESET_TYPE_SIG | \ + (msg)) + +#define BNX2_BC_STATE 0x000001c4 +#define BNX2_BC_STATE_ERR_MASK 0x0000ff00 +#define BNX2_BC_STATE_SIGN 0x42530000 +#define BNX2_BC_STATE_SIGN_MASK 0xffff0000 +#define BNX2_BC_STATE_BC1_START (BNX2_BC_STATE_SIGN | 0x1) +#define BNX2_BC_STATE_GET_NVM_CFG1 (BNX2_BC_STATE_SIGN | 0x2) +#define BNX2_BC_STATE_PROG_BAR (BNX2_BC_STATE_SIGN | 0x3) +#define BNX2_BC_STATE_INIT_VID (BNX2_BC_STATE_SIGN | 0x4) +#define BNX2_BC_STATE_GET_NVM_CFG2 (BNX2_BC_STATE_SIGN | 0x5) +#define BNX2_BC_STATE_APPLY_WKARND (BNX2_BC_STATE_SIGN | 0x6) +#define BNX2_BC_STATE_LOAD_BC2 (BNX2_BC_STATE_SIGN | 0x7) +#define BNX2_BC_STATE_GOING_BC2 (BNX2_BC_STATE_SIGN | 0x8) +#define BNX2_BC_STATE_GOING_DIAG (BNX2_BC_STATE_SIGN | 0x9) +#define BNX2_BC_STATE_RT_FINAL_INIT (BNX2_BC_STATE_SIGN | 0x81) +#define BNX2_BC_STATE_RT_WKARND (BNX2_BC_STATE_SIGN | 0x82) +#define BNX2_BC_STATE_RT_DRV_PULSE (BNX2_BC_STATE_SIGN | 0x83) +#define BNX2_BC_STATE_RT_FIOEVTS (BNX2_BC_STATE_SIGN | 0x84) +#define BNX2_BC_STATE_RT_DRV_CMD (BNX2_BC_STATE_SIGN | 0x85) +#define BNX2_BC_STATE_RT_LOW_POWER (BNX2_BC_STATE_SIGN | 0x86) +#define BNX2_BC_STATE_RT_SET_WOL (BNX2_BC_STATE_SIGN | 0x87) +#define BNX2_BC_STATE_RT_OTHER_FW (BNX2_BC_STATE_SIGN | 0x88) +#define BNX2_BC_STATE_RT_GOING_D3 (BNX2_BC_STATE_SIGN | 0x89) +#define BNX2_BC_STATE_ERR_BAD_VERSION (BNX2_BC_STATE_SIGN | 0x0100) +#define BNX2_BC_STATE_ERR_BAD_BC2_CRC (BNX2_BC_STATE_SIGN | 0x0200) +#define BNX2_BC_STATE_ERR_BC1_LOOP (BNX2_BC_STATE_SIGN | 0x0300) +#define BNX2_BC_STATE_ERR_UNKNOWN_CMD (BNX2_BC_STATE_SIGN | 0x0400) +#define BNX2_BC_STATE_ERR_DRV_DEAD (BNX2_BC_STATE_SIGN | 0x0500) +#define BNX2_BC_STATE_ERR_NO_RXP (BNX2_BC_STATE_SIGN | 0x0600) +#define BNX2_BC_STATE_ERR_TOO_MANY_RBUF (BNX2_BC_STATE_SIGN | 0x0700) + +#define BNX2_BC_STATE_DEBUG_CMD 0x1dc +#define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE 0x42440000 +#define BNX2_BC_STATE_BC_DBG_CMD_SIGNATURE_MASK 0xffff0000 +#define BNX2_BC_STATE_BC_DBG_CMD_LOOP_CNT_MASK 0xffff +#define BNX2_BC_STATE_BC_DBG_CMD_LOOP_INFINITE 0xffff + +#define HOST_VIEW_SHMEM_BASE 0x167c00 + +#endif diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h new file mode 100644 index 000000000000..35f3a2ae5ef1 --- /dev/null +++ b/drivers/net/bnx2_fw.h @@ -0,0 +1,2468 @@ +/* bnx2_fw.h: Broadcom NX2 network driver. + * + * Copyright (c) 2004, 2005 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, except as noted below. + * + * This file contains firmware data derived from proprietary unpublished + * source code, Copyright (c) 2004, 2005 Broadcom Corporation. + * + * Permission is hereby granted for the distribution of this firmware data + * in hexadecimal or equivalent format, provided this copyright notice is + * accompanying it. + */ + + +static int bnx2_COM_b06FwReleaseMajor = 0x0; +static int bnx2_COM_b06FwReleaseMinor = 0x0; +static int bnx2_COM_b06FwReleaseFix = 0x0; +static u32 bnx2_COM_b06FwStartAddr = 0x080004a0; +static u32 bnx2_COM_b06FwTextAddr = 0x08000000; +static int bnx2_COM_b06FwTextLen = 0x4594; +static u32 bnx2_COM_b06FwDataAddr = 0x080045e0; +static int bnx2_COM_b06FwDataLen = 0x0; +static u32 bnx2_COM_b06FwRodataAddr = 0x08004598; +static int bnx2_COM_b06FwRodataLen = 0x18; +static u32 bnx2_COM_b06FwBssAddr = 0x08004600; +static int bnx2_COM_b06FwBssLen = 0x88; +static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0; +static int bnx2_COM_b06FwSbssLen = 0x1c; +static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = { + 0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e, + 0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032, + 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0000ffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000002, 0x00000020, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, + 0x0000000d, 0x3c020800, 0x244245e0, 0x3c030800, 0x24634688, 0xac400000, + 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, + 0x3c100800, 0x261004a0, 0x3c1c0800, 0x279c45e0, 0x0e0001f2, 0x00000000, + 0x0000000d, 0x27bdffe8, 0x3c1a8000, 0x3c020008, 0x0342d825, 0x3c036010, + 0xafbf0010, 0x8c655000, 0x3c020800, 0x24470ac8, 0x3c040800, 0x24864600, + 0x2402ff7f, 0x00a22824, 0x34a5380c, 0xac655000, 0x00002821, 0x24020037, + 0x24030c80, 0xaf420008, 0xaf430024, 0xacc70000, 0x24a50001, 0x2ca20016, + 0x1440fffc, 0x24c60004, 0x24844600, 0x3c020800, 0x24420ad4, 0x3c030800, + 0x246309d4, 0xac820004, 0x3c020800, 0x24420618, 0x3c050800, 0x24a50ca0, + 0xac82000c, 0x3c020800, 0x24423100, 0xac830008, 0x3c030800, 0x246325c8, + 0xac820014, 0x3c020800, 0x24422b0c, 0xac830018, 0xac83001c, 0x3c030800, + 0x24630adc, 0xac820024, 0x3c020800, 0x24423040, 0xac83002c, 0x3c030800, + 0x24633060, 0xac820030, 0x3c020800, 0x24422f6c, 0xac830034, 0x3c030800, + 0x24632c60, 0xac82003c, 0x3c020800, 0x24420b6c, 0xac850010, 0xac850020, + 0xac830040, 0x0e000bd6, 0xac820050, 0x8fbf0010, 0x03e00008, 0x27bd0018, + 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, 0x9203000b, + 0x24020003, 0x1462005b, 0x96110008, 0x32220001, 0x10400009, 0x27430080, + 0x8e020000, 0x96040014, 0x000211c2, 0x00021040, 0x00621821, 0xa4640000, + 0x0a0001cb, 0x3c020800, 0x3c020800, 0x8c430020, 0x1060002a, 0x3c030800, + 0x0e001006, 0x00000000, 0x97420108, 0x8f850018, 0x9743010c, 0x3042003e, + 0x00021400, 0x00621825, 0xaca30000, 0x8f840018, 0x8f420100, 0xac820004, + 0x97430116, 0x9742010e, 0x8f840018, 0x00031c00, 0x00431025, 0xac820008, + 0x97430110, 0x97440112, 0x8f850018, 0x00031c00, 0x00832025, 0xaca4000c, + 0x97420114, 0x8f840018, 0x3042ffff, 0xac820010, 0x8f830018, 0xac600014, + 0x8f820018, 0x3c030800, 0xac400018, 0x9462466e, 0x8f840018, 0x3c032000, + 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x3c030800, 0x8c620040, + 0x24420001, 0xac620040, 0x3c020800, 0x8c430044, 0x32240004, 0x24630001, + 0x10800017, 0xac430044, 0x8f4202b8, 0x04430007, 0x8e020020, 0x3c040800, + 0x8c830060, 0x24020001, 0x24630001, 0x0a0001ed, 0xac830060, 0x3c060800, + 0x8cc4005c, 0xaf420280, 0x96030016, 0x00001021, 0xa7430284, 0x8e050004, + 0x24840001, 0x3c031000, 0xaf450288, 0xaf4302b8, 0x0a0001ed, 0xacc4005c, + 0x32220002, 0x0a0001ed, 0x0002102b, 0x3c026000, 0xac400808, 0x0000000d, + 0x00001021, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, + 0x27bdffc8, 0xafbf0034, 0xafbe0030, 0xafb7002c, 0xafb60028, 0xafb50024, + 0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0x0e00013f, 0xafb00010, + 0x24110020, 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800, + 0x3c170800, 0x3c160800, 0x8f820004, 0x3c040800, 0x8c830020, 0x10430004, + 0x00000000, 0xaf830004, 0x0e00110b, 0x00000000, 0x8f500000, 0x32020007, + 0x1040fff5, 0x32020001, 0x1040002b, 0x32020002, 0x8f420100, 0xaf420020, + 0x8f430104, 0xaf4300a8, 0x9342010b, 0x93630000, 0x306300ff, 0x10710005, + 0x304400ff, 0x10750006, 0x2c820016, 0x0a000227, 0x00000000, 0xaf940000, + 0x0a000228, 0x2c820016, 0xaf930000, 0x0a000228, 0x00000000, 0xaf800000, + 0x14400005, 0x00041880, 0x0e0002b2, 0x00000000, 0x0a000234, 0x00000000, + 0x3c020800, 0x24424600, 0x00621821, 0x8c620000, 0x0040f809, 0x00000000, + 0x10400005, 0x8fc20034, 0x8f420104, 0x3c016020, 0xac220014, 0x8fc20034, + 0xaf520138, 0x24420001, 0xafc20034, 0x32020002, 0x10400019, 0x32020004, + 0x8f420140, 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000, + 0x10750006, 0x00000000, 0x0a000250, 0x00000000, 0xaf940000, 0x0a000251, + 0x00000000, 0xaf930000, 0x0a000251, 0x00000000, 0xaf800000, 0x0e0008b9, + 0x00000000, 0x8ee20038, 0xaf520178, 0x24420001, 0xaee20038, 0x32020004, + 0x1040ffad, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff, + 0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a00026a, 0x00000000, + 0xaf940000, 0x0a00026b, 0x00000000, 0xaf930000, 0x0a00026b, 0x00000000, + 0xaf800000, 0x93620000, 0x14510004, 0x8ec2003c, 0x0e000835, 0x00000000, + 0x8ec2003c, 0xaf5201b8, 0x24420001, 0x0a000206, 0xaec2003c, 0x27bdffe8, + 0xafbf0010, 0x97420108, 0x24033000, 0x30447000, 0x10830012, 0x28823001, + 0x10400007, 0x24024000, 0x1080000b, 0x24022000, 0x1082001a, 0x24020001, + 0x0a000299, 0x00000000, 0x1082000c, 0x24025000, 0x1082000e, 0x00000000, + 0x0a000299, 0x00000000, 0x0000000d, 0x0a00029b, 0x00001021, 0x0e000300, + 0x00000000, 0x0a00029b, 0x00001021, 0x0e00048f, 0x00000000, 0x0a00029b, + 0x00001021, 0x0e000fdf, 0x00000000, 0x0a00029b, 0x00001021, 0x0000000d, + 0x00001021, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x93620000, 0x24030020, + 0x304400ff, 0x10830005, 0x24020030, 0x10820007, 0x00000000, 0x0a0002af, + 0x00000000, 0x2782000c, 0xaf820000, 0x03e00008, 0x00000000, 0x27820008, + 0xaf820000, 0x03e00008, 0x00000000, 0xaf800000, 0x03e00008, 0x00000000, + 0x0000000d, 0x03e00008, 0x00001021, 0x03e00008, 0x00001021, 0x27440100, + 0x94830008, 0x30620004, 0x10400017, 0x30620002, 0x8f4202b8, 0x04430007, + 0x8c820020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001, 0x03e00008, + 0xac830060, 0xaf420280, 0x94830016, 0x3c060800, 0xa7430284, 0x8c850004, + 0x8cc4005c, 0x00001021, 0x3c031000, 0x24840001, 0xaf450288, 0xaf4302b8, + 0x03e00008, 0xacc4005c, 0x14400003, 0x3c040800, 0x03e00008, 0x00001021, + 0x8c830084, 0x24020001, 0x24630001, 0x03e00008, 0xac830084, 0x27450100, + 0x3c040800, 0x8c820088, 0x94a3000c, 0x24420001, 0x007a1821, 0xac820088, + 0x8ca40018, 0x90664000, 0xaf440038, 0x8ca2001c, 0x2403fff8, 0x00063600, + 0x00431024, 0x34420004, 0x3c030005, 0xaf42003c, 0xaf430030, 0x00000000, + 0x00000000, 0x00000000, 0xaf460404, 0x00000000, 0x00000000, 0x00000000, + 0x3c020006, 0x34420001, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, + 0x8f420000, 0x30420010, 0x1040fffd, 0x00001021, 0x03e00008, 0x00000000, + 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x1060001e, + 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020018, 0xac620000, + 0x8f840018, 0x9602000c, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, + 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, + 0x3c026000, 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, + 0x8f850018, 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, + 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffc8, 0xafb3001c, + 0x00009821, 0xafb7002c, 0x0000b821, 0xafbe0030, 0x0000f021, 0xafb50024, + 0x27550100, 0xafbf0034, 0xafb60028, 0xafb40020, 0xafb20018, 0xafb10014, + 0xafb00010, 0x96a20008, 0x8f540100, 0x8eb20018, 0x30420001, 0x10400037, + 0x02a0b021, 0x8f630054, 0x2642ffff, 0x00431023, 0x18400006, 0x00000000, + 0x0000000d, 0x00000000, 0x24000128, 0x0a000372, 0x00002021, 0x8f62004c, + 0x02421023, 0x18400028, 0x00002021, 0x93650120, 0x93640121, 0x3c030800, + 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, 0x00803821, 0x1485000b, + 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, 0xac830090, 0x93620122, + 0x30420001, 0x00021023, 0x30420005, 0x0a000372, 0x34440004, 0x27660100, + 0x00041080, 0x00c21021, 0x8c430000, 0x02431823, 0x04600004, 0x24820001, + 0x30440007, 0x1485fff9, 0x00041080, 0x10870007, 0x3c030800, 0xa3640121, + 0x8c620094, 0x24040005, 0x24420001, 0x0a000372, 0xac620094, 0x24040004, + 0x00809821, 0x9362003f, 0x304400ff, 0x38830016, 0x2c630001, 0x38820010, + 0x2c420001, 0x00621825, 0x1460000c, 0x24020001, 0x38830008, 0x2c630001, + 0x38820014, 0x2c420001, 0x00621825, 0x14600005, 0x24020001, 0x24020012, + 0x14820002, 0x00001021, 0x24020001, 0x50400007, 0x8eb10020, 0x8ea20020, + 0x8f630040, 0x00408821, 0x00431023, 0x5c400001, 0x8f710040, 0x9343010b, + 0x24020004, 0x54620005, 0x36730080, 0x96a20008, 0x36730002, 0x24170001, + 0x305e0020, 0x2402fffb, 0x02628024, 0x1200002a, 0x3c030800, 0x8c620030, + 0x02021024, 0x10400026, 0x3c020800, 0x8c430020, 0x10600024, 0x32620004, + 0x0e001006, 0x00000000, 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, + 0x02201821, 0x32620002, 0xac900004, 0x8f840018, 0x50400001, 0x8ec30014, + 0xac830008, 0x8f830018, 0x8ec20020, 0xac62000c, 0x8f840018, 0x8f620040, + 0xac820010, 0x8f830018, 0x8ec20018, 0xac620014, 0x8f840018, 0x3c026000, + 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024010, + 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x32620004, 0x10400076, + 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02821025, 0xa360007c, + 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, + 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, + 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, + 0x93620023, 0x3042007f, 0xa3620023, 0xaf720064, 0x3c023fff, 0x0a0003f1, + 0x3442ffff, 0x8f62005c, 0x02421023, 0x04400011, 0x00000000, 0x8f65005c, + 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf720064, 0x00a32823, + 0x00852821, 0x0045102b, 0x10400004, 0x02451021, 0x3c053fff, 0x34a5ffff, + 0x02451021, 0xaf62005c, 0x24070001, 0xaf72004c, 0x8f620054, 0x16420005, + 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, + 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, + 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, + 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, + 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, + 0x02821025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, + 0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000, + 0x34420001, 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, + 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02821025, + 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, + 0x3c031000, 0xaf5401c0, 0xa34201c4, 0xaf4301f8, 0x8ea30014, 0x8f620040, + 0x14430003, 0x00431023, 0x0a000443, 0x00001021, 0x28420001, 0x10400034, + 0x00000000, 0x8f620040, 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, + 0x3c029000, 0x93620022, 0x24420001, 0xa3620022, 0x93630022, 0x3c020800, + 0x8c440098, 0x0064182b, 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, + 0x02821025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, + 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02831825, + 0x34420001, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, + 0x24020002, 0x3c031000, 0xaf5401c0, 0xa34201c4, 0x24020001, 0xaf4301f8, + 0xa7620012, 0x0a000476, 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, + 0x3063fffe, 0xa7630012, 0x0e000b68, 0x00000000, 0x12e00003, 0x00000000, + 0x0e000f27, 0x00000000, 0x53c00004, 0x96a20008, 0x0e000c10, 0x00000000, + 0x96a20008, 0x8fbf0034, 0x8fbe0030, 0x8fb7002c, 0x8fb60028, 0x8fb50024, + 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, + 0x30420001, 0x03e00008, 0x27bd0038, 0x27bdffe8, 0xafbf0010, 0x97420108, + 0x2403000b, 0x304400ff, 0x1083004e, 0x2882000c, 0x10400011, 0x24020006, + 0x1082003e, 0x28820007, 0x10400007, 0x28820008, 0x1080002b, 0x24020001, + 0x1082002e, 0x3c026000, 0x0a000504, 0x00000000, 0x14400061, 0x2882000a, + 0x1440002b, 0x00000000, 0x0a0004ec, 0x00000000, 0x2402001c, 0x1082004e, + 0x2882001d, 0x1040000e, 0x24020019, 0x10820041, 0x2882001a, 0x10400005, + 0x2402000e, 0x10820036, 0x00000000, 0x0a000504, 0x00000000, 0x2402001b, + 0x1082003c, 0x00000000, 0x0a000504, 0x00000000, 0x240200c1, 0x10820040, + 0x288200c2, 0x10400005, 0x24020080, 0x1082001f, 0x00000000, 0x0a000504, + 0x00000000, 0x240200c2, 0x1082003b, 0x00000000, 0x0a000504, 0x00000000, + 0x3c026000, 0x0e000c7d, 0xac400808, 0x0a000506, 0x8fbf0010, 0x8c444448, + 0x3c030800, 0xac640064, 0x0e000c7d, 0x00000000, 0x3c026000, 0x8c444448, + 0x3c030800, 0x0a000505, 0xac640068, 0x8f440100, 0x0e000508, 0x00000000, + 0x3c026000, 0x8c444448, 0x3c030800, 0x0a000505, 0xac64006c, 0x0e000cab, + 0x00000000, 0x0a000506, 0x8fbf0010, 0x8f440100, 0x0e000cd5, 0x00000000, + 0x0a000506, 0x8fbf0010, 0x0e000d1c, 0x00000000, 0x0a000506, 0x8fbf0010, + 0x0000000d, 0x0a000506, 0x8fbf0010, 0x0e0005d7, 0x00000000, 0x0a000506, + 0x8fbf0010, 0x8f440100, 0x0e000d7e, 0x00000000, 0x0a000506, 0x8fbf0010, + 0x0e000e95, 0x00000000, 0x0a000506, 0x8fbf0010, 0x0e000626, 0x00000000, + 0x0a000506, 0x8fbf0010, 0x0e000b68, 0x00000000, 0x0a000506, 0x8fbf0010, + 0x0000000d, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c029000, + 0x34420001, 0xafb00010, 0x00808021, 0x02021025, 0x3c038000, 0xafbf0014, + 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, + 0x34420001, 0xa3620005, 0x8f63004c, 0x8f620054, 0x10620019, 0x3c028000, + 0x9762006a, 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, + 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, + 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, + 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, + 0x34420001, 0x02021025, 0x0e000c7d, 0xaf420020, 0x3c029000, 0x34420001, + 0x3c038000, 0x02021025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, + 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02021025, 0xa363007d, + 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x8fbf0014, 0xaf5001c0, + 0x8fb00010, 0x24020002, 0x3c031000, 0xa34201c4, 0xaf4301f8, 0x03e00008, + 0x27bd0018, 0x27bdffd8, 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014, + 0xafb00010, 0x93630005, 0x00809021, 0x24020030, 0x30630030, 0x14620072, + 0x00a09821, 0x3c020800, 0x8c430020, 0x1060006c, 0x00000000, 0x0e001006, + 0x00000000, 0x8f820018, 0xac520000, 0x9363003e, 0x9362003f, 0x8f840018, + 0x00031a00, 0x00431025, 0xac820004, 0x93630081, 0x93620082, 0x8f850018, + 0x00031e00, 0x00021400, 0x00621825, 0xaca30008, 0x8f840018, 0x8f620040, + 0xac82000c, 0x8f830018, 0x8f620048, 0xac620010, 0x8f840018, 0x8f62004c, + 0x3c110800, 0xac820014, 0x8f830018, 0x8f620050, 0x26304660, 0x00002021, + 0xac620018, 0x9602000e, 0x8f850018, 0x3c03c00b, 0x00431025, 0x0e001044, + 0xaca2001c, 0x8f830018, 0x8f620054, 0xac620000, 0x8f840018, 0x8f620058, + 0xac820004, 0x8f830018, 0x8f62005c, 0xac620008, 0x8f840018, 0x8f620060, + 0xac82000c, 0x8f850018, 0x8f620064, 0xaca20010, 0x97630068, 0x9762006a, + 0x8f840018, 0x00031c00, 0x00431025, 0xac820014, 0x8f830018, 0x00002021, + 0xac600018, 0x9602000e, 0x8f850018, 0x3c03c00c, 0x00431025, 0x0e001044, + 0xaca2001c, 0x8f840018, 0x8f630018, 0xac830000, 0x936200c4, 0x30420002, + 0x10400006, 0x00000000, 0x976200c8, 0x8f830018, 0x3042ffff, 0x0a0005b5, + 0xac620004, 0x8f820018, 0xac400004, 0x8f830018, 0x8f62006c, 0xac620008, + 0x8f840018, 0x8f6200dc, 0xac82000c, 0x8f830018, 0xac600010, 0x93620005, + 0x8f830018, 0x00021600, 0x00531025, 0xac620014, 0x8f850018, 0x3c026000, + 0x8c434448, 0x24040001, 0x26224660, 0xaca30018, 0x9443000e, 0x8f850018, + 0x3c02400d, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x02402021, + 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, + 0x27bd0028, 0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, + 0x9603000c, 0x240200c1, 0x5462001d, 0x8e040000, 0x3c029000, 0x8f440100, + 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, 0x8f420020, 0x00431024, + 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, 0x34630001, 0x3c058000, + 0x00831825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00451024, + 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, 0xa34201c4, 0xaf4301f8, + 0x0a000622, 0x8fbf0018, 0x8f65004c, 0x24060001, 0x0e000db5, 0x2407049f, + 0x3c020800, 0x8c430020, 0x9611000c, 0x1060001d, 0x8e100000, 0x0e001006, + 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004, + 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, + 0x8f840018, 0x240204a2, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, + 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, + 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0018, 0x8fb10014, 0x8fb00010, + 0x03e00008, 0x27bd0020, 0x27bdffb0, 0xafb1002c, 0x27510100, 0xafbf004c, + 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034, + 0xafb20030, 0xafb00028, 0x8e350000, 0x9634000c, 0x3c026000, 0x8c434448, + 0x0000f021, 0xaf630170, 0x8f620040, 0x8e230014, 0x0000b821, 0x00431023, + 0x044001ec, 0x0000b021, 0x32820010, 0x1040002e, 0x3c026000, 0x9363003f, + 0x9222000e, 0x10430006, 0x2402000c, 0x9223000f, 0x10620003, 0x24020014, + 0x14620025, 0x3c026000, 0x32820004, 0x10400007, 0x241e0001, 0x8f620050, + 0x24420001, 0xaf620050, 0x8f630054, 0x24630001, 0xaf630054, 0x32830102, + 0x24020002, 0x5462000d, 0x9222000f, 0x8f620040, 0x24420001, 0xaf620040, + 0x8f630048, 0x8f620040, 0x24630001, 0x54620005, 0x9222000f, 0x8f620048, + 0x24420001, 0xaf620048, 0x9222000f, 0xa362003f, 0x9223000f, 0x24020012, + 0x14620007, 0x3c026000, 0x3c030800, 0x8c620074, 0x24420001, 0x0e000f6e, + 0xac620074, 0x3c026000, 0x8c434448, 0x32820040, 0xaf630174, 0x32830020, + 0xafa30010, 0x32830080, 0xafa30014, 0x32830001, 0xafa3001c, 0x32830008, + 0xafa30020, 0x32830100, 0x104000bb, 0xafa30018, 0x8e260010, 0x8f630054, + 0x24c2ffff, 0x00431023, 0x18400006, 0x00000000, 0x0000000d, 0x00000000, + 0x24000128, 0x0a0006b2, 0x00009021, 0x8f62004c, 0x00c21023, 0x18400028, + 0x00009021, 0x93650120, 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, + 0x24420001, 0x30a500ff, 0x00804021, 0x1485000b, 0xac62008c, 0x3c040800, + 0x8c830090, 0x24630001, 0xac830090, 0x93620122, 0x30420001, 0x00021023, + 0x30420005, 0x0a0006b2, 0x34520004, 0x27670100, 0x00041080, 0x00e21021, + 0x8c430000, 0x00c31823, 0x04600004, 0x24820001, 0x30440007, 0x1485fff9, + 0x00041080, 0x10880007, 0x3c030800, 0xa3640121, 0x8c620094, 0x24120005, + 0x24420001, 0x0a0006b2, 0xac620094, 0x24120004, 0x32420001, 0x10400020, + 0x3c020800, 0x8c430020, 0x8e300000, 0x1060001c, 0x8e330010, 0x0e001006, + 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, + 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, + 0x8f820018, 0xac530014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, + 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024010, 0x00621825, + 0x0e001044, 0xaca3001c, 0x32420004, 0x10400060, 0x00003821, 0x3c029000, + 0x8e260010, 0x34420001, 0x3c038000, 0x02a21025, 0xa360007c, 0xaf420020, + 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, 0x30420080, + 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, 0x8f620064, + 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, 0x93620023, + 0x3042007f, 0xa3620023, 0xaf660064, 0x3c023fff, 0x0a000702, 0x3442ffff, + 0x8f62005c, 0x00c21023, 0x04400011, 0x00000000, 0x8f65005c, 0x8f630064, + 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf660064, 0x00a32823, 0x00852821, + 0x0045102b, 0x10400004, 0x00c51021, 0x3c053fff, 0x34a5ffff, 0x00c51021, + 0xaf62005c, 0x24070001, 0xaf66004c, 0x8f620054, 0x14c20005, 0x00000000, + 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, 0x00022880, + 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, + 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, + 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, 0x2403fffe, + 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, 0x02a21025, + 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620005, 0x00e0b021, + 0x0e000f2a, 0x00000000, 0x00403821, 0x00e0b021, 0x8fa20010, 0x10400008, + 0x00000000, 0x8e220018, 0xaf620018, 0x8e23001c, 0xaf63001c, 0x8e220020, + 0x24160001, 0xaf620058, 0x13c00036, 0x32820004, 0x10400035, 0x8fa30014, + 0x93620023, 0x30420040, 0x10400031, 0x3c020800, 0x8c430020, 0x1060001c, + 0x8e300000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018, + 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, + 0xac400010, 0x8f830018, 0x24020587, 0xac620014, 0x8f850018, 0x3c026000, + 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, + 0x3c024019, 0x00621825, 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, + 0x02a21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, + 0x24020001, 0xaf62000c, 0x93630023, 0x3c028000, 0x34420001, 0x02a21025, + 0x306300bf, 0xa3630023, 0xaf420020, 0x8fa30014, 0x10600012, 0x8fa3001c, + 0x9362007c, 0x24420001, 0xa362007c, 0x9363007e, 0x9362007a, 0x1462000b, + 0x8fa3001c, 0x9362007c, 0x3c030800, 0x8c640024, 0x0044102b, 0x14400005, + 0x8fa3001c, 0x0e000f2a, 0x00000000, 0x02c2b025, 0x8fa3001c, 0x3062ffff, + 0x10400003, 0x32820200, 0x0a000793, 0x24170004, 0x10400003, 0x00000000, + 0x24170040, 0x24160001, 0x13c0005d, 0x32820002, 0x1040005c, 0x8fa20020, + 0x9222000a, 0x30420020, 0x10400033, 0x3c100800, 0x93620023, 0x30420040, + 0x1040002f, 0x8e020020, 0x1040001e, 0x3c029000, 0x0e001006, 0x00000000, + 0x8f820018, 0xac550000, 0x8f840018, 0x3c02008d, 0xac820004, 0x8f830018, + 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f840018, + 0x240205bf, 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, + 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825, + 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02a21025, 0xaf420020, + 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023, + 0x3c028000, 0x34420001, 0x02a21025, 0x306300bf, 0xa3630023, 0xaf420020, + 0x8e020020, 0x10400023, 0x8fa20020, 0x0e001006, 0x00000000, 0x8f840018, + 0x8e230000, 0xac830000, 0x9222000a, 0x8f830018, 0x00021600, 0xac620004, + 0x8f840018, 0x8f620040, 0xac820008, 0x8f850018, 0x8f63004c, 0xaca3000c, + 0x9362003f, 0x8f840018, 0x304200ff, 0xac820010, 0x8f830018, 0x3c026000, + 0xac600014, 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, + 0x9443466e, 0x8f850018, 0x3c02401a, 0x00621825, 0x0e001044, 0xaca3001c, + 0x8fa20020, 0x1040000e, 0x8fa20018, 0x9222000a, 0xa3620082, 0x56e00005, + 0x36f70008, 0x8fa30018, 0x10600004, 0x00000000, 0x36f70008, 0x0a000801, + 0x24160001, 0x0e000de1, 0x02a02021, 0x8fa20018, 0x10400003, 0x00000000, + 0x36f70010, 0x24160001, 0x12c00019, 0x3c029000, 0x34420001, 0x02a21025, + 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, + 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, 0x02a31825, 0x02e21025, + 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, + 0x3c031000, 0xaf5501c0, 0xa34201c4, 0xaf4301f8, 0x9363003f, 0x24020012, + 0x14620004, 0x3c026000, 0x0e000f6e, 0x00000000, 0x3c026000, 0x8c434448, + 0xaf630178, 0x8fbf004c, 0x8fbe0048, 0x8fb70044, 0x8fb60040, 0x8fb5003c, + 0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x03e00008, + 0x27bd0050, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f500180, 0x97420184, + 0x30420200, 0x14400015, 0x00000000, 0x8f430188, 0x3c02ff00, 0x00621824, + 0x3c020200, 0x10620031, 0x0043102b, 0x14400007, 0x3c020300, 0x1060000b, + 0x3c020100, 0x1062000d, 0x00000000, 0x0a0008b4, 0x00000000, 0x10620027, + 0x3c020400, 0x1062003e, 0x02002021, 0x0a0008b4, 0x00000000, 0x0e000e1e, + 0x02002021, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420020, 0x1440005e, + 0x8fbf0014, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, + 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, + 0x34630001, 0x02031825, 0x34420020, 0xa3620005, 0xaf430020, 0x93620005, + 0x30420020, 0x14400003, 0x02002021, 0x0000000d, 0x02002021, 0x0e000553, + 0x24055854, 0x0a0008b6, 0x8fbf0014, 0x93620005, 0x30420001, 0x1040003f, + 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, 0x3c038000, 0x8f420020, + 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, 0x3c048000, 0x3c030800, + 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, 0x02042025, 0xaf440020, + 0x1040002d, 0x8fbf0014, 0x0a000894, 0x00000000, 0x00002821, 0x00003021, + 0x0e000f78, 0x240706a4, 0x3c020800, 0x8c430020, 0x10600023, 0x8fbf0014, + 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x93630082, 0x9362003f, + 0x8f840018, 0x00031a00, 0x00431025, 0xac820004, 0x8f830018, 0xac600008, + 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, + 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, + 0x9443466e, 0x8f850018, 0x3c02400a, 0x00621825, 0x0e001044, 0xaca3001c, + 0x0a0008b6, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, 0x03e00008, + 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93420148, 0x2444ffff, 0x2c830005, + 0x10600047, 0x3c020800, 0x24424598, 0x00041880, 0x00621821, 0x8c640000, + 0x00800008, 0x00000000, 0x8f430144, 0x8f62000c, 0x14620006, 0x24020001, + 0xaf62000c, 0x0e000909, 0x00000000, 0x0a000907, 0x8fbf0010, 0x8f62000c, + 0x0a000900, 0x00000000, 0x97630010, 0x8f420144, 0x14430006, 0x24020001, + 0xa7620010, 0x0e000eeb, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620010, + 0x0a000900, 0x00000000, 0x97630012, 0x8f420144, 0x14430006, 0x24020001, + 0xa7620012, 0x0e000f06, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620012, + 0x0a000900, 0x00000000, 0x97630014, 0x8f420144, 0x14430006, 0x24020001, + 0xa7620014, 0x0e000f21, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620014, + 0x0a000900, 0x00000000, 0x97630016, 0x8f420144, 0x14430006, 0x24020001, + 0xa7620016, 0x0e000f24, 0x00000000, 0x0a000907, 0x8fbf0010, 0x97620016, + 0x14400006, 0x8fbf0010, 0x3c030800, 0x8c620070, 0x24420001, 0xac620070, + 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x93620081, + 0x3c030800, 0x8c640048, 0x0044102b, 0x14400028, 0x3c029000, 0x8f460140, + 0x34420001, 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, + 0x1440fffd, 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, + 0x24020012, 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, + 0xaf440020, 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, + 0x9362007d, 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, + 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, + 0x0a00096d, 0xaf4601c0, 0x93620081, 0x24420001, 0x0e000f2a, 0xa3620081, + 0x9763006a, 0x00032880, 0x14a00002, 0x00403821, 0x24050001, 0x97630068, + 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, + 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, + 0x00c02021, 0x8f420074, 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, + 0x10e0001a, 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, + 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, + 0x9362007d, 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, + 0xaf430020, 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, + 0xaf4401c0, 0xa34201c4, 0xaf4301f8, 0x8fbf0010, 0x03e00008, 0x27bd0018, + 0x27bdffd8, 0xafb3001c, 0x27530100, 0xafbf0024, 0xafb40020, 0xafb20018, + 0xafb10014, 0xafb00010, 0x96620008, 0x3c140800, 0x8f520100, 0x30420001, + 0x104000cf, 0x00000000, 0x8e700018, 0x8f630054, 0x2602ffff, 0x00431023, + 0x18400006, 0x00000000, 0x0000000d, 0x00000000, 0x24000128, 0x0a0009b6, + 0x00008821, 0x8f62004c, 0x02021023, 0x18400028, 0x00008821, 0x93650120, + 0x93640121, 0x3c030800, 0x8c62008c, 0x308400ff, 0x24420001, 0x30a500ff, + 0x00803821, 0x1485000b, 0xac62008c, 0x3c040800, 0x8c830090, 0x24630001, + 0xac830090, 0x93620122, 0x30420001, 0x00021023, 0x30420005, 0x0a0009b6, + 0x34510004, 0x27660100, 0x00041080, 0x00c21021, 0x8c430000, 0x02031823, + 0x04600004, 0x24820001, 0x30440007, 0x1485fff9, 0x00041080, 0x10870007, + 0x3c030800, 0xa3640121, 0x8c620094, 0x24110005, 0x24420001, 0x0a0009b6, + 0xac620094, 0x24110004, 0x32220001, 0x1040001e, 0x8e820020, 0x1040001d, + 0x32220004, 0x0e001006, 0x00000000, 0x8f820018, 0xac520000, 0x8f840018, + 0x24020001, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, + 0x8f830018, 0xac600010, 0x8f820018, 0xac500014, 0x8f850018, 0x3c026000, + 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, + 0x3c024010, 0x00621825, 0x0e001044, 0xaca3001c, 0x32220004, 0x10400076, + 0x00003821, 0x3c029000, 0x34420001, 0x3c038000, 0x02421025, 0xa360007c, + 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620023, + 0x30420080, 0x10400011, 0x00000000, 0x8f65005c, 0x8f63004c, 0x9764003c, + 0x8f620064, 0x00a32823, 0x00852821, 0x00a2102b, 0x54400006, 0x3c023fff, + 0x93620023, 0x3042007f, 0xa3620023, 0xaf700064, 0x3c023fff, 0x0a000a03, + 0x3442ffff, 0x8f62005c, 0x02021023, 0x04400011, 0x00000000, 0x8f65005c, + 0x8f630064, 0x9764003c, 0x3c023fff, 0x3442ffff, 0xaf700064, 0x00a32823, + 0x00852821, 0x0045102b, 0x10400004, 0x02051021, 0x3c053fff, 0x34a5ffff, + 0x02051021, 0xaf62005c, 0x24070001, 0xaf70004c, 0x8f620054, 0x16020005, + 0x00000000, 0x93620023, 0x30420040, 0x10400017, 0x24020001, 0x9762006a, + 0x00022880, 0x50a00001, 0x24050001, 0x97630068, 0x93640081, 0x3c020800, + 0x8c46004c, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, + 0x3c020800, 0x8c440050, 0x00c4182b, 0x54600001, 0x00c02021, 0x8f420074, + 0x2403fffe, 0x00832824, 0x00a21021, 0xaf62000c, 0x3c028000, 0x34420001, + 0x02421025, 0xa3600081, 0xaf420020, 0x9363007e, 0x9362007a, 0x10620004, + 0x00000000, 0x0e000f2a, 0x00000000, 0x00403821, 0x10e00017, 0x3c029000, + 0x34420001, 0x02421025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, + 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, 0x3c048000, 0x02421025, + 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, + 0x3c031000, 0xaf5201c0, 0xa34201c4, 0xaf4301f8, 0x9342010b, 0x8e830020, + 0x27500100, 0x38420006, 0x10600029, 0x2c510001, 0x0e001006, 0x00000000, + 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x96020008, 0xac820004, + 0x8f830018, 0x8e020014, 0xac620008, 0x8f850018, 0x3c026000, 0x8c434448, + 0xaca3000c, 0x8f840018, 0x96020012, 0xac820010, 0x8f850018, 0x8e030020, + 0xaca30014, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, 0x00431025, + 0xac820018, 0x12200005, 0x3c020800, 0x9443466e, 0x8f840018, 0x0a000a78, + 0x3c024013, 0x9443466e, 0x8f840018, 0x3c024014, 0x00621825, 0xac83001c, + 0x0e001044, 0x24040001, 0x8e630014, 0x8f620040, 0x14430003, 0x00431023, + 0x0a000a83, 0x00001021, 0x28420001, 0x10400034, 0x00000000, 0x8f620040, + 0xaf630040, 0x9362003e, 0x30420001, 0x1440000b, 0x3c029000, 0x93620022, + 0x24420001, 0xa3620022, 0x93630022, 0x3c020800, 0x8c440098, 0x0064182b, + 0x1460001e, 0x3c020800, 0x3c029000, 0x34420001, 0x02421025, 0xaf420020, + 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, + 0x9362007d, 0x34630001, 0x3c048000, 0x02431825, 0x34420001, 0xa362007d, + 0xaf430020, 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, + 0xaf5201c0, 0xa34201c4, 0x24020001, 0xaf4301f8, 0xa7620012, 0x0a000ab6, + 0xa3600022, 0x9743007a, 0x9444002a, 0x00641821, 0x3063fffe, 0xa7630012, + 0x0e000b68, 0x00000000, 0x97420108, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, + 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x00021042, 0x30420001, 0x03e00008, + 0x27bd0028, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020, 0xafb00010, + 0x27500100, 0xafbf001c, 0x10400046, 0xafb10014, 0x0e001006, 0x00000000, + 0x8f840018, 0x8e020000, 0xac820000, 0x936300b1, 0x936200c5, 0x8f850018, + 0x00031e00, 0x00021400, 0x34420100, 0x00621825, 0xaca30004, 0x8f840018, + 0x8e02001c, 0xac820008, 0x8f830018, 0x8f620048, 0xac62000c, 0x8f840018, + 0x96020012, 0xac820010, 0x8f830018, 0x8f620040, 0x24040001, 0xac620014, + 0x8f850018, 0x3c026000, 0x8c434448, 0x3c020800, 0x24514660, 0xaca30018, + 0x9623000e, 0x8f850018, 0x3c024016, 0x00621825, 0x0e001044, 0xaca3001c, + 0x96030008, 0x30630010, 0x1060001c, 0x8e420020, 0x1040001a, 0x8e100000, + 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, 0x8f830018, 0xac600004, + 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, + 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, 0x8c634448, 0x24040001, + 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, 0x00431025, 0x0e001044, + 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, + 0x03e00008, 0x27bd0020, 0x27bdffe0, 0xafb20018, 0x3c120800, 0x8e420020, + 0xafb00010, 0x27500100, 0xafbf001c, 0x10400041, 0xafb10014, 0x0e001006, + 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x24020100, + 0xac820004, 0x8f830018, 0x8e02001c, 0xac620008, 0x8f840018, 0x8e020018, + 0xac82000c, 0x8f830018, 0x96020012, 0xac620010, 0x8f840018, 0x96020008, + 0xac820014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, + 0x24514660, 0xaca30018, 0x9623000e, 0x8f850018, 0x3c024017, 0x00621825, + 0x0e001044, 0xaca3001c, 0x96030008, 0x30630010, 0x1060001c, 0x8e420020, + 0x1040001a, 0x8e100000, 0x0e001006, 0x00000000, 0x8f820018, 0xac500000, + 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, 0x8f830018, 0xac60000c, + 0x8f820018, 0xac400010, 0x8f830018, 0xac600014, 0x8f850018, 0x3c036000, + 0x8c634448, 0x24040001, 0xaca30018, 0x9622000e, 0x8f850018, 0x3c034015, + 0x00431025, 0x0e001044, 0xaca2001c, 0x00001021, 0x8fbf001c, 0x8fb20018, + 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0xafbf0010, + 0x936200c4, 0x30420002, 0x10400019, 0x00000000, 0x936200c5, 0x936300b1, + 0x00431023, 0x304400ff, 0x30830080, 0x10600004, 0x00000000, 0x0000000d, + 0x00000000, 0x24000a6a, 0x93620004, 0x00441023, 0x304400ff, 0x30830080, + 0x10600004, 0x2482ffff, 0x8f650024, 0x0a000b82, 0x00000000, 0x00022b00, + 0x8f620024, 0x0045102b, 0x10400002, 0x00000000, 0x8f650024, 0x8f620048, + 0x8f630040, 0x00431823, 0x0065202b, 0x10800004, 0x00000000, 0x8f620040, + 0x00451021, 0xaf620048, 0x9762003c, 0x0062102b, 0x10400041, 0x8fbf0010, + 0x10a0003f, 0x3c029000, 0x34420001, 0x3c040800, 0x8c830080, 0x8f450100, + 0x3c068000, 0x24630001, 0x00a21025, 0xac830080, 0xaf420020, 0x8f420020, + 0x00461024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, 0x3c048000, + 0x00a31825, 0x34420004, 0xa362007d, 0xaf430020, 0x8f4201f8, 0x00441024, + 0x1440fffd, 0x24020002, 0x3c030800, 0xaf4501c0, 0xa34201c4, 0x8c640020, + 0x3c021000, 0xaf4201f8, 0x1080001f, 0x8fbf0010, 0x0e001006, 0x00000000, + 0x8f830018, 0x8f420100, 0xac620000, 0x8f840018, 0x8f620040, 0xac820004, + 0x8f850018, 0x8f620048, 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, + 0xac400010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, 0x8c434448, + 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c0240c2, 0x00621825, + 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0010, 0x03e00008, 0x27bd0018, + 0x3c020800, 0x24423958, 0xaf82000c, 0x03e00008, 0x00000000, 0x27bdffe8, + 0xafb00010, 0x27500100, 0xafbf0014, 0x8e02001c, 0x14400003, 0x3c020800, + 0x0000000d, 0x3c020800, 0x8c430020, 0x10600026, 0x00001021, 0x0e001006, + 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, 0x8e02001c, + 0xac820004, 0x8f830018, 0xac600008, 0x8f840018, 0x8e020018, 0xac82000c, + 0x8f850018, 0x96020012, 0xaca20010, 0x8f830018, 0x3c106000, 0xac600014, + 0x8f840018, 0x8e024448, 0x3c030800, 0xac820018, 0x9462466e, 0x8f840018, + 0x3c034012, 0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x8e036800, + 0x00001021, 0x3c040001, 0x00641825, 0xae036800, 0x0a000c0d, 0x8fbf0014, + 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x97430078, + 0x9444002e, 0x00001021, 0x00641821, 0x3063fffe, 0x03e00008, 0xa7630010, + 0x27450100, 0x8f640048, 0x8ca30018, 0x00641023, 0x18400021, 0x00000000, + 0xaf630048, 0x8f620040, 0x9763003c, 0x00821023, 0x0043102a, 0x1040001a, + 0x3c029000, 0x8ca40000, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, + 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, + 0x34630001, 0x3c058000, 0x00831825, 0x34420004, 0xa362007d, 0xaf430020, + 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, + 0xa34201c4, 0xaf4301f8, 0x03e00008, 0x00001021, 0x8f420100, 0x34420001, + 0xaf4200a4, 0x03e00008, 0x00001021, 0x27bdffe0, 0xafbf0018, 0xafb10014, + 0xafb00010, 0x9362007e, 0x30d000ff, 0x16020029, 0x00808821, 0x93620080, + 0x16020026, 0x00000000, 0x9362007f, 0x16020023, 0x00000000, 0x9362007a, + 0x16020004, 0x00000000, 0x0000000d, 0x00000000, 0x24000771, 0x0e000f49, + 0x00000000, 0x3c039000, 0x34630001, 0x3c048000, 0x02231825, 0xa370007a, + 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, 0x3c028000, 0x9363007d, + 0x34420001, 0x3c048000, 0x02221025, 0xa363007d, 0xaf420020, 0x8f4201f8, + 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf5101c0, 0xa34201c4, + 0xaf4301f8, 0x0a000c79, 0x8fbf0018, 0x0000000d, 0x00000000, 0x24000781, + 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, + 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, 0x10600024, 0xafbf0014, + 0x0e001006, 0x00000000, 0x8f830018, 0x8e020000, 0xac620000, 0x8f840018, + 0x8e020004, 0xac820004, 0x8f830018, 0x8e020018, 0xac620008, 0x8f840018, + 0x8e03001c, 0xac83000c, 0x9602000c, 0x9203000a, 0x8f840018, 0x00021400, + 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, + 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018, + 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014, + 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, + 0xafb00010, 0x27500100, 0x10600020, 0xafbf0014, 0x0e001006, 0x00000000, + 0x8f820018, 0xac400000, 0x8f830018, 0xac600004, 0x8f820018, 0xac400008, + 0x8f830018, 0xac60000c, 0x9602000c, 0x9603000e, 0x8f840018, 0x00021400, + 0x00431025, 0xac820010, 0x8f830018, 0x3c026000, 0xac600014, 0x8f840018, + 0x8c434448, 0xac830018, 0x96020008, 0x3c030800, 0x9464466e, 0x8f850018, + 0x00021400, 0x00441025, 0x24040001, 0x0e001044, 0xaca2001c, 0x8fbf0014, + 0x8fb00010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafb00010, 0x27500100, + 0xafbf0014, 0x9602000c, 0x10400024, 0x00802821, 0x3c020800, 0x8c430020, + 0x1060003a, 0x8fbf0014, 0x0e001006, 0x00000000, 0x8f840018, 0x8e030000, + 0xac830000, 0x9602000c, 0x8f840018, 0x00021400, 0xac820004, 0x8f830018, + 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, + 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, 0x3c020800, + 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02400b, 0x00621825, 0x0e001044, + 0xaca3001c, 0x0a000d19, 0x8fbf0014, 0x93620005, 0x30420010, 0x14400015, + 0x3c029000, 0x34420001, 0x00a21025, 0xaf420020, 0x3c038000, 0x8f420020, + 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x93620005, 0x34630001, + 0x00a02021, 0x00a31825, 0x24055852, 0x34420010, 0xa3620005, 0x0e000553, + 0xaf430020, 0x0a000d19, 0x8fbf0014, 0x0000000d, 0x8fbf0014, 0x8fb00010, + 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, + 0x27500100, 0x10600022, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f840018, + 0x8e020004, 0xac820000, 0x9603000c, 0x9762002c, 0x8f840018, 0x00031c00, + 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, + 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, + 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, + 0x3c02400e, 0x00621825, 0x0e001044, 0xaca3001c, 0x0e000d48, 0x8e040000, + 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c038000, 0x8f420278, + 0x00431024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf440240, 0xa3420244, + 0x03e00008, 0xaf430278, 0x3c020800, 0x8c430020, 0x27bdffe0, 0xafb10014, + 0x00808821, 0xafb20018, 0x00c09021, 0xafb00010, 0x30b0ffff, 0x1060001c, + 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, 0xac510000, 0x8f840018, + 0x00101400, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, + 0x8f830018, 0xac600010, 0x8f820018, 0xac520014, 0x8f840018, 0x3c026000, + 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c024019, + 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf001c, 0x8fb20018, + 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x27bdffe8, 0x27450100, + 0xafbf0010, 0x94a3000c, 0x240200c1, 0x14620029, 0x00803021, 0x3c029000, + 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, + 0x1440fffd, 0x3c028000, 0x34420001, 0x3c049000, 0x34840001, 0x3c058000, + 0x24030012, 0x00c21025, 0x00c42025, 0xa363003f, 0xaf420020, 0xaf440020, + 0x8f420020, 0x00451024, 0x1440fffd, 0x3c038000, 0x9362007d, 0x34630001, + 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, 0x8f4201f8, + 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, + 0xaf4301f8, 0x0a000db3, 0x8fbf0010, 0x00c02021, 0x94a5000c, 0x24060001, + 0x0e000f78, 0x240706d8, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, + 0x8c430020, 0x27bdffe0, 0xafb00010, 0x00808021, 0xafb20018, 0x00a09021, + 0xafb10014, 0x30d100ff, 0x1060001c, 0xafbf001c, 0x0e001006, 0x00000000, + 0x8f820018, 0xac500000, 0x8f840018, 0x24020001, 0xac820004, 0x8f830018, + 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, 0x8f820018, + 0xac520014, 0x8f840018, 0x3c026000, 0x8c434448, 0x3c020800, 0xac830018, + 0x9443466e, 0x8f840018, 0x3c024010, 0x00621825, 0xac83001c, 0x0e001044, + 0x02202021, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, + 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x93620005, 0x30420001, + 0x10400033, 0x00808021, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, + 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93620005, + 0x3c048000, 0x3c030800, 0x304200fe, 0xa3620005, 0x8c620020, 0x34840001, + 0x02042025, 0xaf440020, 0x10400020, 0x8fbf0014, 0x0e001006, 0x00000000, + 0x8f820018, 0xac500000, 0x93630082, 0x9362003f, 0x8f840018, 0x00031a00, + 0x00431025, 0xac820004, 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, + 0x8f830018, 0xac600010, 0x8f820018, 0xac400014, 0x8f840018, 0x3c026000, + 0x8c434448, 0x3c020800, 0xac830018, 0x9443466e, 0x8f840018, 0x3c02400a, + 0x00621825, 0xac83001c, 0x0e001044, 0x24040001, 0x8fbf0014, 0x8fb00010, + 0x03e00008, 0x27bd0018, 0x27bdffe8, 0xafbf0010, 0x8f420188, 0x00803021, + 0x9364003f, 0x24030012, 0x00021402, 0x1483001c, 0x304500ff, 0x3c029000, + 0x34420001, 0x3c038000, 0x00c21025, 0xa3650080, 0xa365007a, 0xaf420020, + 0x8f420020, 0x00431024, 0x1440fffd, 0x3c028000, 0x9363007d, 0x34420001, + 0x3c048000, 0x00c21025, 0xa363007d, 0xaf420020, 0x8f4201f8, 0x00441024, + 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, 0xa34201c4, 0xaf4301f8, + 0x0a000e54, 0x8fbf0010, 0x9362007e, 0x1445000e, 0x00000000, 0x93620080, + 0x1045000b, 0x00000000, 0xa3650080, 0x8f820000, 0x93660080, 0x8f440180, + 0x8f65004c, 0x8c430000, 0x0060f809, 0x00000000, 0x0a000e54, 0x8fbf0010, + 0xa3650080, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x3c020800, 0x8c430020, + 0x27bdffe0, 0xafb10014, 0x00808821, 0xafb20018, 0x00a09021, 0xafb00010, + 0x30d000ff, 0x1060002f, 0xafbf001c, 0x0e001006, 0x00000000, 0x8f820018, + 0xac510000, 0x8f830018, 0xac700004, 0x8f820018, 0xac520008, 0x8f830018, + 0xac60000c, 0x8f820018, 0xac400010, 0x9763006a, 0x00032880, 0x50a00001, + 0x24050001, 0x97630068, 0x93640081, 0x3c020800, 0x8c46004c, 0x00652821, + 0x00852804, 0x00c5102b, 0x54400001, 0x00a03021, 0x3c020800, 0x8c440050, + 0x00c4182b, 0x54600001, 0x00c02021, 0x8f830018, 0x2402fffe, 0x00822824, + 0x3c026000, 0xac650014, 0x8f840018, 0x8c434448, 0x3c020800, 0xac830018, + 0x9443466e, 0x8f840018, 0x3c024011, 0x00621825, 0xac83001c, 0x0e001044, + 0x24040001, 0x8fbf001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x03e00008, + 0x27bd0020, 0x27bdffe8, 0xafbf0014, 0xafb00010, 0x8f440100, 0x27500100, + 0x8f650050, 0x0e000c45, 0x9206001b, 0x3c020800, 0x8c430020, 0x1060001d, + 0x8e100018, 0x0e001006, 0x00000000, 0x8f840018, 0x8f420100, 0xac820000, + 0x8f830018, 0xac700004, 0x8f840018, 0x8f620050, 0xac820008, 0x8f830018, + 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, 0x3c026000, 0xac600014, + 0x8f850018, 0x8c434448, 0x24040001, 0x3c020800, 0xaca30018, 0x9443466e, + 0x8f850018, 0x3c02401c, 0x00621825, 0x0e001044, 0xaca3001c, 0x8fbf0014, + 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c029000, 0x8f460140, 0x34420001, + 0x3c038000, 0x00c21025, 0xaf420020, 0x8f420020, 0x00431024, 0x1440fffd, + 0x3c048000, 0x34840001, 0x3c059000, 0x34a50001, 0x3c078000, 0x24020012, + 0x24030080, 0x00c42025, 0x00c52825, 0xa362003f, 0xa3630082, 0xaf440020, + 0xaf450020, 0x8f420020, 0x00471024, 0x1440fffd, 0x3c038000, 0x9362007d, + 0x34630001, 0x3c048000, 0x00c31825, 0x34420020, 0xa362007d, 0xaf430020, + 0x8f4201f8, 0x00441024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4601c0, + 0xa34201c4, 0x03e00008, 0xaf4301f8, 0x8f430238, 0x3c020800, 0x04610013, + 0x8c44009c, 0x2406fffe, 0x3c050800, 0x3c038000, 0x2484ffff, 0x14800009, + 0x00000000, 0x97420078, 0x8ca3007c, 0x24420001, 0x00461024, 0x24630001, + 0xa7620010, 0x03e00008, 0xaca3007c, 0x8f420238, 0x00431024, 0x1440fff3, + 0x2484ffff, 0x8f420140, 0x3c031000, 0xaf420200, 0x03e00008, 0xaf430238, + 0x3c029000, 0x8f440140, 0x34420001, 0x3c038000, 0x00821025, 0xaf420020, + 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x3c038000, 0x9362007d, + 0x34630001, 0x3c058000, 0x00831825, 0x34420001, 0xa362007d, 0xaf430020, + 0x8f4201f8, 0x00451024, 0x1440fffd, 0x24020002, 0x3c031000, 0xaf4401c0, + 0xa34201c4, 0x03e00008, 0xaf4301f8, 0x0000000d, 0x03e00008, 0x00000000, + 0x0000000d, 0x03e00008, 0x00000000, 0x24020001, 0x03e00008, 0xa7620010, + 0x9362003f, 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, + 0x00621825, 0x14600003, 0x24020012, 0x14820003, 0x00000000, 0x03e00008, + 0x00001021, 0x9363007e, 0x9362007a, 0x14620006, 0x00000000, 0x9363007e, + 0x24020001, 0x24630001, 0x03e00008, 0xa363007e, 0x9363007e, 0x93620080, + 0x14620004, 0x24020001, 0xa362000b, 0x03e00008, 0x24020001, 0x03e00008, + 0x00001021, 0x9362000b, 0x10400021, 0x00001021, 0xa360000b, 0x9362003f, + 0x304400ff, 0x3883000e, 0x2c630001, 0x38820010, 0x2c420001, 0x00621825, + 0x14600015, 0x00001821, 0x24020012, 0x10820012, 0x00000000, 0x9363007e, + 0x9362007a, 0x14620007, 0x00000000, 0x9362007e, 0x24030001, 0x24420001, + 0xa362007e, 0x03e00008, 0x00601021, 0x9363007e, 0x93620080, 0x14620004, + 0x00001821, 0x24020001, 0xa362000b, 0x24030001, 0x03e00008, 0x00601021, + 0x03e00008, 0x00000000, 0x24040001, 0xaf64000c, 0x8f6300dc, 0x8f6200cc, + 0x50620001, 0xa7640010, 0xa7640012, 0xa7640014, 0x03e00008, 0xa7640016, + 0x27bdffd8, 0xafb00010, 0x00808021, 0xafb3001c, 0x00c09821, 0xafbf0020, + 0xafb20018, 0xafb10014, 0x93620023, 0x00e09021, 0x30420040, 0x10400020, + 0x30b1ffff, 0x3c020800, 0x8c430020, 0x1060001c, 0x00000000, 0x0e001006, + 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x3c02008d, 0xac820004, + 0x8f830018, 0xac600008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, + 0x8f820018, 0xac520014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, + 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c024019, 0x00621825, + 0x0e001044, 0xaca3001c, 0x93620023, 0x30420020, 0x14400003, 0x3c020800, + 0x52600020, 0x3c029000, 0x8c430020, 0x1060001d, 0x3c029000, 0x0e001006, + 0x00000000, 0x8f820018, 0xac500000, 0x8f840018, 0x00111400, 0xac820004, + 0x8f830018, 0xac720008, 0x8f820018, 0xac40000c, 0x8f830018, 0xac600010, + 0x8f820018, 0xac400014, 0x8f850018, 0x3c026000, 0x8c434448, 0x24040001, + 0x3c020800, 0xaca30018, 0x9443466e, 0x8f850018, 0x3c02401b, 0x00621825, + 0x0e001044, 0xaca3001c, 0x3c029000, 0x34420001, 0x02021025, 0xaf420020, + 0x3c038000, 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x93630023, + 0x3c028000, 0x34420001, 0x02021025, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, + 0x8fb10014, 0x8fb00010, 0x3063009f, 0xa3630023, 0xaf420020, 0x03e00008, + 0x27bd0028, 0x3c020800, 0x8c430020, 0x27bdffe8, 0xafb00010, 0x27500100, + 0x1060001d, 0xafbf0014, 0x0e001006, 0x00000000, 0x8f830018, 0x8e020004, + 0xac620000, 0x8f840018, 0x8e020018, 0xac820004, 0x8f850018, 0x8e020000, + 0xaca20008, 0x8f830018, 0xac60000c, 0x8f820018, 0xac400010, 0x8f830018, + 0xac600014, 0x8f820018, 0xac400018, 0x96030008, 0x3c020800, 0x9444466e, + 0x8f850018, 0x00031c00, 0x00641825, 0x24040001, 0x0e001044, 0xaca3001c, + 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, 0x3c060800, 0x24c54660, + 0x3c02000a, 0x03421821, 0x94640006, 0x94a2000a, 0x00441023, 0x00021400, + 0x00021c03, 0x04610006, 0xa4a40006, 0x0000000d, 0x00000000, 0x2400005a, + 0x0a00101b, 0x24020001, 0x8f820014, 0x0062102b, 0x14400002, 0x00001021, + 0x24020001, 0x304200ff, 0x1040001c, 0x274a0400, 0x3c07000a, 0x3c020800, + 0x24454660, 0x94a9000a, 0x8f880014, 0x03471021, 0x94430006, 0x00402021, + 0xa4a30006, 0x94820006, 0xa4a20006, 0x01221023, 0x00021400, 0x00021403, + 0x04410006, 0x0048102b, 0x0000000d, 0x00000000, 0x2400005a, 0x0a001036, + 0x24020001, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1440ffec, + 0x03471021, 0x24c44660, 0x8c820010, 0xaf420038, 0x8c830014, 0x3c020005, + 0xaf43003c, 0xaf420030, 0xaf800010, 0xaf8a0018, 0x03e00008, 0x00000000, + 0x27bdffe0, 0x8f820010, 0x8f850018, 0x3c070800, 0x24e84660, 0xafbf001c, + 0xafb20018, 0xafb10014, 0xafb00010, 0x9503000a, 0x8d060014, 0x00009021, + 0x309000ff, 0x00e08821, 0x24420001, 0x24a50020, 0x24630001, 0xaf820010, + 0xaf850018, 0xa503000a, 0x24c30020, 0x3c028000, 0x04c10007, 0xad030014, + 0x00621024, 0x14400005, 0x26224660, 0x8d020010, 0x24420001, 0xad020010, + 0x26224660, 0x9444000a, 0x94450018, 0x0010102b, 0x00a41826, 0x2c630001, + 0x00621825, 0x1060001c, 0x3c030006, 0x8f820010, 0x24120001, 0x00021140, + 0x00431025, 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27450400, + 0x8f420000, 0x30420010, 0x1040fffd, 0x26224660, 0x9444000a, 0x94430018, + 0xaf800010, 0xaf850018, 0x14830012, 0x26274660, 0x0e0010d2, 0x00000000, + 0x1600000e, 0x26274660, 0x0e001006, 0x00000000, 0x0a00108f, 0x26274660, + 0x00041c00, 0x00031c03, 0x00051400, 0x00021403, 0x00621823, 0x18600002, + 0x3c026000, 0xac400808, 0x26274660, 0x94e2000e, 0x94e3000c, 0x24420001, + 0xa4e2000e, 0x3042ffff, 0x50430001, 0xa4e0000e, 0x12000005, 0x3c02000a, + 0x94e2000a, 0xa74200a2, 0x0a0010cc, 0x02401021, 0x03421821, 0x94640006, + 0x94e2000a, 0x00441023, 0x00021400, 0x00021c03, 0x04610006, 0xa4e40006, + 0x0000000d, 0x00000000, 0x2400005a, 0x0a0010ae, 0x24020001, 0x8f820014, + 0x0062102b, 0x14400002, 0x00001021, 0x24020001, 0x304200ff, 0x1040001b, + 0x3c020800, 0x3c06000a, 0x24454660, 0x94a8000a, 0x8f870014, 0x03461021, + 0x94430006, 0x00402021, 0xa4a30006, 0x94820006, 0xa4a20006, 0x01021023, + 0x00021400, 0x00021403, 0x04410006, 0x0047102b, 0x0000000d, 0x00000000, + 0x2400005a, 0x0a0010c8, 0x24020001, 0x14400002, 0x00001021, 0x24020001, + 0x304200ff, 0x1440ffec, 0x03461021, 0x02401021, 0x8fbf001c, 0x8fb20018, + 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3c020800, 0x24454660, + 0x94a3001a, 0x8ca40024, 0x00403021, 0x000318c0, 0x00832021, 0xaf44003c, + 0x8ca20020, 0xaf420038, 0x3c020050, 0x34420008, 0xaf420030, 0x00000000, + 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, 0x00000000, + 0x8f430400, 0x24c64660, 0xacc30010, 0x8f420404, 0x3c030020, 0xacc20014, + 0xaf430030, 0x94c40018, 0x94c3001c, 0x94c2001a, 0x94c5001e, 0x00832021, + 0x24420001, 0xa4c2001a, 0x3042ffff, 0x14450002, 0xa4c40018, 0xa4c0001a, + 0x03e00008, 0x00000000, 0x8f820010, 0x3c030006, 0x00021140, 0x00431025, + 0xaf420030, 0x00000000, 0x00000000, 0x00000000, 0x27430400, 0x8f420000, + 0x30420010, 0x1040fffd, 0x00000000, 0xaf800010, 0xaf830018, 0x03e00008, + 0x00000000, 0x27bdffe8, 0xafb00010, 0x3c100800, 0x26104660, 0x3c05000a, + 0x02002021, 0x03452821, 0xafbf0014, 0x0e001128, 0x2406000a, 0x96020002, + 0x9603001e, 0x3042000f, 0x24420003, 0x00431804, 0x24027fff, 0x0043102b, + 0xaf830014, 0x10400004, 0x00000000, 0x0000000d, 0x00000000, 0x24000043, + 0x0e0010d2, 0x00000000, 0x8fbf0014, 0x8fb00010, 0x03e00008, 0x27bd0018, + 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, + 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a001137, 0x00a01021, + 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, + 0x00000000, 0x3c036000, 0x8c642b7c, 0x3c036010, 0x8c6553fc, 0x00041582, + 0x00042302, 0x308403ff, 0x00052d82, 0x00441026, 0x0002102b, 0x0005282b, + 0x00451025, 0x1440000d, 0x3c020050, 0x34420004, 0xaf400038, 0xaf40003c, + 0xaf420030, 0x00000000, 0x00000000, 0x8f420000, 0x30420020, 0x1040fffd, + 0x3c020020, 0xaf420030, 0x0000000d, 0x03e00008, 0x00000000, 0x3c020050, + 0x34420004, 0xaf440038, 0xaf45003c, 0xaf420030, 0x00000000, 0x00000000, + 0x8f420000, 0x30420020, 0x1040fffd, 0x3c020020, 0xaf420030, 0x03e00008, + 0x00000000, 0x00000000 }; + +static u32 bnx2_COM_b06FwData[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_COM_b06FwRodata[(0x18/4) + 1] = { + 0x08002318, 0x08002348, 0x08002378, 0x080023a8, 0x080023d8, 0x00000000, + 0x00000000 }; + +static u32 bnx2_COM_b06FwBss[(0x88/4) + 1] = { 0x00000000 }; +static u32 bnx2_COM_b06FwSbss[(0x1c/4) + 1] = { 0x00000000 }; + +static int bnx2_RXP_b06FwReleaseMajor = 0x0; +static int bnx2_RXP_b06FwReleaseMinor = 0x0; +static int bnx2_RXP_b06FwReleaseFix = 0x0; +static u32 bnx2_RXP_b06FwStartAddr = 0x08000060; +static u32 bnx2_RXP_b06FwTextAddr = 0x08000000; +static int bnx2_RXP_b06FwTextLen = 0x20b8; +static u32 bnx2_RXP_b06FwDataAddr = 0x080020e0; +static int bnx2_RXP_b06FwDataLen = 0x0; +static u32 bnx2_RXP_b06FwRodataAddr = 0x00000000; +static int bnx2_RXP_b06FwRodataLen = 0x0; +static u32 bnx2_RXP_b06FwBssAddr = 0x08002100; +static int bnx2_RXP_b06FwBssLen = 0x239c; +static u32 bnx2_RXP_b06FwSbssAddr = 0x080020e0; +static int bnx2_RXP_b06FwSbssLen = 0x14; + +static u32 bnx2_RXP_b06FwText[(0x20b8/4) + 1] = { + 0x0a000018, 0x00000000, 0x00000000, 0x0000000d, 0x72787020, 0x302e362e, + 0x39000000, 0x00060903, 0x00000000, 0x0000000d, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, + 0x244220e0, 0x3c030800, 0x2463449c, 0xac400000, 0x0043202b, 0x1480fffd, + 0x24420004, 0x3c1d0800, 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100060, + 0x3c1c0800, 0x279c20e0, 0x0e000329, 0x00000000, 0x0000000d, 0x8f870008, + 0x2ce20080, 0x10400018, 0x3c030800, 0x24633490, 0x8f460100, 0x00072140, + 0x00831021, 0xac460000, 0x8f450104, 0x00641021, 0xac450004, 0x8f460108, + 0xac460008, 0x8f45010c, 0xac45000c, 0x8f460114, 0xac460010, 0x8f450118, + 0xac450014, 0x8f460124, 0xac460018, 0x8f450128, 0x00641821, 0x24e20001, + 0xaf820008, 0xac65001c, 0x03e00008, 0x00000000, 0x00804021, 0x8f830000, + 0x24070001, 0x3c020001, 0x00621024, 0x10400037, 0x00603021, 0x9742010e, + 0x3c038000, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, + 0xa342018b, 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, + 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000069, 0x00021400, + 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, + 0x24020003, 0x30838000, 0x1060000d, 0xa7420188, 0x93420116, 0x304200fc, + 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600005, 0x00000000, + 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, + 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, + 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30c21000, + 0x1040000f, 0x00000000, 0x9742010c, 0x3042fc00, 0x5440000b, 0x24070005, + 0x3c021000, 0x00c21024, 0x10400007, 0x3c030dff, 0x3463ffff, 0x3c020e00, + 0x00c21024, 0x0062182b, 0x54600001, 0x24070005, 0x8f82000c, 0x30434000, + 0x10600016, 0x00404821, 0x3c020f00, 0x00c21024, 0x14400012, 0x00000000, + 0x93420116, 0x34424000, 0x03421821, 0x94650002, 0x2ca21389, 0x1040000b, + 0x3c020800, 0x24422100, 0x00051942, 0x00031880, 0x00621821, 0x30a5001f, + 0x8c640000, 0x24020001, 0x00a21004, 0x00822024, 0x01044025, 0x11000037, + 0x3c021000, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, 0x3045ffff, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, + 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, + 0x9743011c, 0x9742011e, 0x0a0000cd, 0x00021400, 0x9743011e, 0x9742011c, + 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, + 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, + 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, + 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, + 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x03e00008, + 0x00001021, 0x00c21024, 0x104000ba, 0x3c020800, 0x8c430030, 0x1060003e, + 0x31224000, 0x1040003c, 0x3c030f00, 0x00c31824, 0x3c020100, 0x0043102b, + 0x14400038, 0x3c030800, 0x9742010e, 0x34e60002, 0x3c038000, 0x24420004, + 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, + 0x8f840004, 0x24020080, 0x24030002, 0xaf420180, 0xa743018c, 0x10800005, + 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000110, 0x00021400, 0x9743011e, + 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, + 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, + 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, + 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, + 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, + 0x03e00008, 0x00001021, 0x3c030800, 0x8c620024, 0x30420008, 0x1040003d, + 0x34e80002, 0x3c020f00, 0x00c21024, 0x5440003a, 0x3107ffff, 0x9742010c, + 0x30420200, 0x50400036, 0x3107ffff, 0x9742010e, 0x30e6fffb, 0x3c038000, + 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, + 0xa342018b, 0x8f840004, 0x24020180, 0x24030002, 0xaf420180, 0xa743018c, + 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000153, 0x00021400, + 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, + 0x30828000, 0x1040000c, 0xa7460188, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x3107ffff, 0x8f820000, 0x3c068000, 0x9743010e, 0x00021442, + 0x30440780, 0x24630004, 0x3065ffff, 0x8f4201b8, 0x00461024, 0x1440fffd, + 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf440180, 0xa742018c, + 0x10600005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000189, 0x00021400, + 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, + 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x03e00008, 0x00001021, 0x8f424000, 0x30420100, 0x104000ef, + 0x3c020800, 0x8c440024, 0x24030001, 0x14830036, 0x00404021, 0x9742010e, + 0x34e50002, 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, + 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0001c6, + 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, + 0x8f84000c, 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, + 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, + 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, + 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, + 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x30820001, 0x10400035, + 0x30e90004, 0x9742010e, 0x30e6fffb, 0x3c038000, 0x24420004, 0x3044ffff, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, + 0x24020002, 0xaf400180, 0xa742018c, 0x10600005, 0xa744018e, 0x9743011c, + 0x9742011e, 0x0a0001fe, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, + 0x00621825, 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, + 0x93420116, 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, + 0x14600004, 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, + 0x9743010c, 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, + 0xa74201a6, 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x30c7ffff, 0x8d020024, + 0x30420004, 0x10400037, 0x8d020024, 0x9742010e, 0x30e6fffb, 0x3c038000, + 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020003, + 0xa342018b, 0x8f840004, 0x24020100, 0x24030002, 0xaf420180, 0xa743018c, + 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, 0x0a000237, 0x00021400, + 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, + 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x30c7ffff, 0x8d020024, 0x30420008, 0x10400034, 0x00000000, + 0x9742010e, 0x3c038000, 0x24420004, 0x3045ffff, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x24020003, 0xa342018b, 0x8f840004, 0x24020180, 0x24030002, + 0xaf420180, 0xa743018c, 0x10800005, 0xa745018e, 0x9743011c, 0x9742011e, + 0x0a00026f, 0x00021400, 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, + 0xaf4301a8, 0x8f84000c, 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, + 0x304200fc, 0x005a1021, 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, + 0x3c02ffff, 0x34427fff, 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, + 0x8f440104, 0x3042bfff, 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, + 0xaf4301ac, 0x3c021000, 0xaf4201b8, 0x15200046, 0x00001021, 0x3c038000, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, + 0xa7430188, 0x3c021000, 0xaf4201b8, 0x03e00008, 0x00001021, 0x3c030800, + 0x8c620024, 0x30420001, 0x10400035, 0x00001021, 0x9742010e, 0x34e50002, + 0x3c038000, 0x24420004, 0x3044ffff, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x24020003, 0xa342018b, 0x8f830004, 0x24020002, 0xaf400180, 0xa742018c, + 0x10600005, 0xa744018e, 0x9743011c, 0x9742011e, 0x0a0002b5, 0x00021400, + 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, + 0x30828000, 0x1040000c, 0xa7450188, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x00001021, 0x03e00008, 0x00000000, 0x27bdffe0, 0xafbf0018, + 0xafb10014, 0xafb00010, 0x8f420140, 0xaf420020, 0x8f430148, 0x3c027000, + 0x00621824, 0x3c024000, 0x1062000c, 0x0043102b, 0x14400006, 0x3c025000, + 0x3c023000, 0x1062000b, 0x3c024000, 0x0a00031f, 0x00000000, 0x10620034, + 0x3c024000, 0x0a00031f, 0x00000000, 0x0e00067c, 0x00000000, 0x0a00031f, + 0x3c024000, 0x8f420148, 0x24030002, 0x3044ffff, 0x00021402, 0x305000ff, + 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, 0x24020003, 0x0600001d, + 0x36053000, 0x0a00030a, 0x3c038000, 0x12020007, 0x00000000, 0x0a000317, + 0x00000000, 0x0e000423, 0x00000000, 0x0a000308, 0x00402021, 0x0e000435, + 0x00000000, 0x00402021, 0x36053000, 0x3c038000, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, 0xa6240010, 0x8f420144, + 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00031f, 0x3c024000, 0x0000000d, + 0x00000000, 0x240001c3, 0x0a00031f, 0x3c024000, 0x0e0007f7, 0x00000000, + 0x3c024000, 0xaf420178, 0x00000000, 0x8fbf0018, 0x8fb10014, 0x8fb00010, + 0x03e00008, 0x27bd0020, 0x24020800, 0x03e00008, 0xaf4201b8, 0x27bdffe8, + 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, + 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008, + 0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001, + 0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400, + 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, + 0x34420200, 0xae021980, 0x8f500000, 0x32020003, 0x1040fffd, 0x32020001, + 0x10400004, 0x32020002, 0x0e0003bd, 0x00000000, 0x32020002, 0x1040fff6, + 0x00000000, 0x0e0002d4, 0x00000000, 0x0a00034a, 0x00000000, 0x27bdffe8, + 0x3c04600c, 0xafbf0014, 0xafb00010, 0x8c825000, 0x3c1a8000, 0x2403ff7f, + 0x3c106000, 0x00431024, 0x3442380c, 0x24030003, 0xac825000, 0x3c040008, + 0xaf430008, 0x8e020808, 0x3c030800, 0xac600020, 0x3042fff0, 0x2c420001, + 0xaf820004, 0x0e000819, 0x0344d825, 0x0e000781, 0x00000000, 0x3c020400, + 0x3442000c, 0x3c03ffff, 0x34630806, 0xae021948, 0xae03194c, 0x8e021980, + 0x8fbf0014, 0x34420200, 0xae021980, 0x8fb00010, 0x03e00008, 0x27bd0018, + 0x30a5ffff, 0x30c6ffff, 0x30e7ffff, 0x3c038000, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x24020003, 0xa342018b, 0x8f830004, 0xaf440180, 0xa745018c, + 0x10600005, 0xa746018e, 0x9743011c, 0x9742011e, 0x0a000393, 0x00021400, + 0x9743011e, 0x9742011c, 0x00021400, 0x00621825, 0xaf4301a8, 0x8f84000c, + 0x30828000, 0x1040000c, 0xa7470188, 0x93420116, 0x304200fc, 0x005a1021, + 0x24424004, 0x8c430000, 0x3063ffff, 0x14600004, 0x3c02ffff, 0x34427fff, + 0x00821024, 0xaf82000c, 0x9782000e, 0x9743010c, 0x8f440104, 0x3042bfff, + 0x00031c00, 0x3084ffff, 0x00641825, 0xa74201a6, 0xaf4301ac, 0x3c021000, + 0xaf4201b8, 0x03e00008, 0x00000000, 0x3c038000, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x24020002, 0x24032000, 0xa342018b, 0xa7430188, 0x3c021000, + 0xaf4201b8, 0x03e00008, 0x00000000, 0x27bdffe8, 0xafbf0010, 0x8f460128, + 0xaf460020, 0x8f420104, 0x8f450100, 0x24030800, 0x3c040010, 0xaf820000, + 0x00441024, 0xaf85000c, 0xaf4301b8, 0x14400005, 0x3c02001f, 0x3c030800, + 0x8c620020, 0x0a0003d5, 0x00002021, 0x3442ff00, 0x14c20009, 0x2402bfff, + 0x3c030800, 0x8c620020, 0x24040001, 0x24420001, 0x0e00004c, 0xac620020, + 0x0a0003e4, 0x00000000, 0x00a21024, 0x14400006, 0x00000000, 0xaf400048, + 0x0e000448, 0xaf400040, 0x0a0003e4, 0x00000000, 0x0e000783, 0x00000000, + 0x10400005, 0x3c024000, 0x8f430124, 0x3c026020, 0xac430014, 0x3c024000, + 0xaf420138, 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, + 0xafbf0018, 0xafb10014, 0xafb00010, 0x8f420148, 0x24030002, 0x3044ffff, + 0x00021402, 0x305000ff, 0x1203000c, 0x27510180, 0x2a020003, 0x10400005, + 0x24020003, 0x0600001d, 0x36053000, 0x0a00040e, 0x3c038000, 0x12020007, + 0x00000000, 0x0a00041b, 0x00000000, 0x0e000423, 0x00000000, 0x0a00040c, + 0x00402021, 0x0e000435, 0x00000000, 0x00402021, 0x36053000, 0x3c038000, + 0x8f4201b8, 0x00431024, 0x1440fffd, 0x24020002, 0xa6250008, 0xa222000b, + 0xa6240010, 0x8f420144, 0x3c031000, 0xae220024, 0xaf4301b8, 0x0a00041f, + 0x8fbf0018, 0x0000000d, 0x00000000, 0x240001c3, 0x8fbf0018, 0x8fb10014, + 0x8fb00010, 0x03e00008, 0x27bd0020, 0x3084ffff, 0x2c821389, 0x1040000d, + 0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821, + 0x3086001f, 0x8ca40000, 0x24030001, 0x00c31804, 0x00832025, 0x03e00008, + 0xaca40000, 0x03e00008, 0x24020091, 0x3084ffff, 0x2c821389, 0x1040000e, + 0x00001021, 0x3c030800, 0x24632100, 0x00042942, 0x00052880, 0x00a32821, + 0x3086001f, 0x24030001, 0x8ca40000, 0x00c31804, 0x00031827, 0x00832024, + 0x03e00008, 0xaca40000, 0x03e00008, 0x24020091, 0x27bdffb0, 0x3c026000, + 0xafbf0048, 0x8c434448, 0xaf630140, 0x93620005, 0x30420001, 0x14400005, + 0x00000000, 0x0e0007ed, 0x00000000, 0x0a00067a, 0x8fbf0048, 0x93420116, + 0x93430112, 0x8f430104, 0x3c040020, 0x34424000, 0x00641824, 0x1060000d, + 0x03426021, 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x24040008, + 0x240340c1, 0xa4430008, 0x24030002, 0xa043000b, 0x3c031000, 0x0a000563, + 0xa044000a, 0x8f420104, 0x3c030040, 0x00431024, 0x10400007, 0x00000000, + 0x8f430128, 0x27420180, 0xac430000, 0x8f650040, 0x0a00055c, 0x24040010, + 0xaf400048, 0xaf400054, 0xaf400040, 0x8f630048, 0x8f620040, 0x00624823, + 0x05210004, 0x00000000, 0x0000000d, 0x00000000, 0x24000132, 0x9742011a, + 0x3046ffff, 0x10c00004, 0x8d880004, 0x01061021, 0x0a000487, 0x2445ffff, + 0x01002821, 0x918a000d, 0xa7a00020, 0xafa00028, 0x9364003f, 0x3c026000, + 0x8c434448, 0x308700ff, 0x31420004, 0x10400033, 0xaf630144, 0x24090012, + 0x14e90006, 0x3c040800, 0x8c830028, 0x24020001, 0x24630001, 0x0a00054e, + 0xac830028, 0x8f620044, 0x15020012, 0x97a20020, 0x27a60010, 0x27450180, + 0x3442001a, 0xa7a20020, 0x8f630040, 0x3c048000, 0x24020020, 0xa3a70022, + 0xa3a90023, 0xa3a2001a, 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, + 0x00000000, 0x0a000533, 0x00000000, 0x8f620044, 0x01021023, 0x0440009e, + 0x24020001, 0x8f620048, 0x01021023, 0x0441009a, 0x24020001, 0x97a20020, + 0x27a60010, 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, + 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, + 0x00000000, 0x3c026000, 0x8c424448, 0xaf620148, 0x8f630040, 0x00685823, + 0x19600013, 0x00cb102a, 0x54400007, 0x314a00fe, 0x5566000c, 0x010b4021, + 0x31420001, 0x54400009, 0x010b4021, 0x314a00fe, 0x24020001, 0xa7a20020, + 0x8f630040, 0x00c05821, 0x00003021, 0x0a0004dd, 0xafa30028, 0x00cb1023, + 0x0a0004dd, 0x3046ffff, 0x00005821, 0x8f620048, 0x2442ffff, 0x00a21823, + 0x18600019, 0x0066102a, 0x14400013, 0x24020001, 0xa7a20020, 0x8f630040, + 0xafa30028, 0x8f620040, 0x55020005, 0x27a60010, 0x55200003, 0x27a60010, + 0x0a0004f6, 0x00c01821, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x8f650048, 0x00c31023, + 0x3046ffff, 0x314a00f6, 0x3c046000, 0x8c824448, 0x31430002, 0x1060001e, + 0xaf62014c, 0x8f620044, 0x1502000e, 0x97a20020, 0x27a60010, 0x34420200, + 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, 0x8f4201b8, + 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, 0x27a60010, + 0x34420001, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, 0xafa30028, + 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x0a000533, 0x00000000, + 0x3c026000, 0x8c424448, 0x31430010, 0xaf620150, 0x54600003, 0x8d890008, + 0x0a00054e, 0x24020001, 0x8f630054, 0x2522ffff, 0x00431023, 0x1840002a, + 0x24020001, 0x27a60010, 0xa7a20020, 0x8f630040, 0x27450180, 0x3c048000, + 0xafa30028, 0x8f4201b8, 0x00441024, 0x1440fffd, 0x00000000, 0x8f420128, + 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, 0xaca30018, 0x90c4000a, + 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, 0xa4a20010, 0x90c30012, + 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, 0xaca30014, 0x8cc20024, + 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc4002c, 0x24020001, 0x3c031000, + 0xaca4002c, 0xaf4301b8, 0xaf400044, 0xaf400050, 0x0a00067a, 0x8fbf0048, + 0x3c026000, 0x8c424448, 0x31430020, 0x10600019, 0xaf620154, 0x8f430128, + 0x27420180, 0xac430000, 0x8f650040, 0x24040004, 0x240340c1, 0xa4430008, + 0x24030002, 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, + 0xa0400012, 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, + 0xac450018, 0x0e0007ed, 0xaf4301b8, 0x0a00067a, 0x8fbf0048, 0x8f430104, + 0x8c824448, 0x38e3000a, 0x2c630001, 0xaf620158, 0x38e2000c, 0x2c420001, + 0x00621825, 0x14600003, 0x2402000e, 0x14e2002a, 0x00000000, 0x50c00008, + 0x9584000e, 0x10c00004, 0xa7a60040, 0x01061021, 0x0a000583, 0x2445ffff, + 0x01002821, 0x9584000e, 0x93630035, 0x8f62004c, 0x00642004, 0x00892021, + 0x00821023, 0x1840001f, 0x3c026000, 0x8f620018, 0x01021023, 0x1c40000f, + 0x97a20020, 0x8f620018, 0x15020018, 0x3c026000, 0x8f62001c, 0x01221023, + 0x1c400008, 0x97a20020, 0x8f62001c, 0x15220011, 0x3c026000, 0x8f620058, + 0x00821023, 0x1840000c, 0x97a20020, 0xafa50028, 0xafa80034, 0xafa90038, + 0xafa4003c, 0x34420020, 0x0a0005a8, 0xa7a20020, 0x8f680040, 0x00003021, + 0x8f640058, 0x01002821, 0x3c026000, 0x8c434448, 0xaf63015c, 0x8f62004c, + 0x01221023, 0x18400009, 0x00000000, 0x8f620054, 0x01221023, 0x1c400005, + 0x97a20020, 0xafa50028, 0xafa90024, 0x0a0005c3, 0x34420040, 0x9742011a, + 0x1440000c, 0x24020014, 0x8f620058, 0x14820009, 0x24020014, 0x8f63004c, + 0x8f620054, 0x10620004, 0x97a20020, 0xafa50028, 0x34420080, 0xa7a20020, + 0x24020014, 0x10e2000a, 0x28e20015, 0x10400005, 0x2402000c, 0x10e20006, + 0x3c026000, 0x0a000600, 0x00000000, 0x24020016, 0x14e20031, 0x3c026000, + 0x8f620054, 0x24420001, 0x1522002d, 0x3c026000, 0x24020014, 0x10e2001e, + 0x28e20015, 0x10400005, 0x2402000c, 0x10e20008, 0x3c026000, 0x0a000600, + 0x00000000, 0x24020016, 0x10e2000c, 0x97a20020, 0x0a000600, 0x3c026000, + 0x97a30020, 0x2402000e, 0xafa50028, 0xa3a70022, 0xa3a20023, 0xafa90024, + 0x34630054, 0x0a0005ff, 0xa7a30020, 0x24030010, 0x24040002, 0xafa50028, + 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0xafa90024, 0x0a0005fe, 0x3442005d, + 0x97a20020, 0x24030012, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, + 0xa3a4001a, 0xafa90024, 0x3042fffe, 0x3442005c, 0xa7a20020, 0x3c026000, + 0x8c434448, 0x31420001, 0xaf630160, 0x1040002c, 0x2402000c, 0x10e20014, + 0x28e2000d, 0x10400005, 0x2402000a, 0x10e20008, 0x97a20020, 0x0a000631, + 0x3c026000, 0x2402000e, 0x10e20018, 0x3c026000, 0x0a000631, 0x00000000, + 0x24030008, 0x24040002, 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, + 0x0a00062f, 0x34420013, 0x97a30020, 0x30620004, 0x1440000b, 0x97a20020, + 0x3462001b, 0xa7a20020, 0x24020016, 0x24030002, 0xafa50028, 0xa3a70022, + 0xa3a20023, 0x0a000630, 0xa3a3001a, 0x97a20020, 0x24030010, 0x24040002, + 0xafa50028, 0xa3a70022, 0xa3a30023, 0xa3a4001a, 0x3442001b, 0xa7a20020, + 0x3c026000, 0x8c434448, 0x31420009, 0x0002102b, 0x00021023, 0x30420007, + 0x34440003, 0xaf630164, 0x10c00016, 0x24030800, 0x8f820010, 0x27450180, + 0x24420001, 0xaf820010, 0x24020004, 0xaf4301b8, 0xa4a40008, 0xa0a2000b, + 0x93440120, 0x3c031000, 0xa4a6000e, 0xaca90024, 0xaca80028, 0x008b2021, + 0xa4a4000c, 0xaf4301b8, 0x97a20020, 0x00003021, 0x3042ffbf, 0x0a000650, + 0xa7a20020, 0x24060001, 0x3c026000, 0x8c434448, 0xaf630168, 0x97a20020, + 0x10400020, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x00000000, 0x8f420128, 0xaca20000, 0x8fa30028, 0x240240c1, 0xa4a20008, + 0xaca30018, 0x93a4001a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x97a20020, + 0xa4a20010, 0x93a30022, 0xa0a30012, 0x93a20023, 0xa0a20013, 0x8fa30024, + 0xaca30014, 0x8fa20034, 0xaca20024, 0x8fa30038, 0xaca30028, 0x8fa2003c, + 0x3c031000, 0xaca2002c, 0xaf4301b8, 0x3c026000, 0x8c434448, 0x00c01021, + 0xaf63016c, 0x8fbf0048, 0x03e00008, 0x27bd0050, 0x8f460140, 0x8f470148, + 0x3c028000, 0x00e24024, 0x00072c02, 0x30a300ff, 0x2402000b, 0x1062008f, + 0x27440180, 0x2862000c, 0x10400011, 0x24020006, 0x1062005a, 0x28620007, + 0x10400007, 0x24020008, 0x10600024, 0x24020001, 0x10620037, 0x00000000, + 0x0a00077e, 0x00000000, 0x106200a9, 0x24020009, 0x106200bb, 0x00071c02, + 0x0a00077e, 0x00000000, 0x2402001b, 0x106200c7, 0x2862001c, 0x10400007, + 0x2402000e, 0x106200b1, 0x24020019, 0x106200c2, 0x00071c02, 0x0a00077e, + 0x00000000, 0x24020080, 0x10620060, 0x28620081, 0x10400005, 0x2402001c, + 0x10620094, 0x00071c02, 0x0a00077e, 0x00000000, 0x240200c2, 0x106200c5, + 0x00a01821, 0x0a00077e, 0x00000000, 0x00a01821, 0x3c058000, 0x8f4201b8, + 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, 0xac860000, + 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, 0x3c021000, + 0xac800028, 0xac830024, 0x3c036000, 0xaf4201b8, 0x03e00008, 0xac600808, + 0x11000009, 0x00a01821, 0x3c020800, 0x24030002, 0xa0434490, 0x24424490, + 0xac460008, 0x8f430144, 0x03e00008, 0xac430004, 0x3c058000, 0x8f4201b8, + 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, 0xac860004, 0xa4830008, + 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, 0x8f420144, 0x3c031000, + 0xac820028, 0x3c026000, 0xaf4301b8, 0x03e00008, 0xac400808, 0x00a01821, + 0x3c080800, 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x00000000, + 0xac860000, 0x91024490, 0x00002821, 0x10400002, 0x25064490, 0x8cc50008, + 0xac850004, 0xa4830008, 0x91034490, 0x24020002, 0xa082000b, 0xa4870010, + 0x34630001, 0xa083000a, 0x8f420144, 0xac820024, 0x91034490, 0x10600002, + 0x00001021, 0x8cc20004, 0xac820028, 0x3c021000, 0xaf4201b8, 0x3c026000, + 0xa1004490, 0x03e00008, 0xac400808, 0x00a01821, 0x3c058000, 0x8f4201b8, + 0x00451024, 0x1440fffd, 0x24020002, 0xa082000b, 0xa4830008, 0xa4870010, + 0x8f420144, 0x3c031000, 0xa4820012, 0x03e00008, 0xaf4301b8, 0x30e2ffff, + 0x14400028, 0x00071c02, 0x93620005, 0x30420004, 0x14400020, 0x3c029000, + 0x34420001, 0x00c21025, 0xaf420020, 0x3c038000, 0x8f420020, 0x00431024, + 0x1440fffd, 0x00000000, 0x93620005, 0x3c038000, 0x34630001, 0x00c31825, + 0x34420004, 0xa3620005, 0xaf430020, 0x93620005, 0x30420004, 0x14400003, + 0x3c038000, 0x0000000d, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x24020005, 0x3c031000, 0xac860000, 0xa082000b, 0xaf4301b8, 0x0a00073d, + 0x00071c02, 0x0000000d, 0x03e00008, 0x00000000, 0x00071c02, 0x3c058000, + 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, 0x24030002, + 0xac860000, 0xac800004, 0xa082000a, 0xa083000b, 0xa4870010, 0x8f430144, + 0x3c021000, 0xac800028, 0xac830024, 0x03e00008, 0xaf4201b8, 0x00071c02, + 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac800000, + 0xac860004, 0xa4830008, 0xa082000a, 0xa082000b, 0xa4870010, 0xac800024, + 0x8f420144, 0x3c031000, 0xac820028, 0x03e00008, 0xaf4301b8, 0x00071c02, + 0x3c058000, 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020001, 0xa4830008, + 0x24030002, 0xa082000a, 0x3c021000, 0xac860000, 0xac800004, 0xa083000b, + 0xa4870010, 0xac800024, 0xac800028, 0x03e00008, 0xaf4201b8, 0x3c058000, + 0x8f4201b8, 0x00451024, 0x1440fffd, 0x24020002, 0xac860000, 0xac800004, + 0xa4830008, 0xa080000a, 0x0a000748, 0xa082000b, 0x0000000d, 0x03e00008, + 0x00000000, 0x03e00008, 0x00000000, 0x8f420100, 0x3042003e, 0x14400011, + 0x24020001, 0xaf400048, 0x8f420100, 0x304207c0, 0x10400005, 0x00000000, + 0xaf40004c, 0xaf400050, 0x03e00008, 0x24020001, 0xaf400054, 0xaf400040, + 0x8f420100, 0x30423800, 0x54400001, 0xaf400044, 0x24020001, 0x03e00008, + 0x00000000, 0x3c029000, 0x34420001, 0x00822025, 0xaf440020, 0x3c038000, + 0x8f420020, 0x00431024, 0x1440fffd, 0x00000000, 0x03e00008, 0x00000000, + 0x3c028000, 0x34420001, 0x00822025, 0x03e00008, 0xaf440020, 0x8f430128, + 0x27420180, 0xac430000, 0x8f650040, 0x240340c1, 0xa4430008, 0x24030002, + 0xa044000a, 0x24040008, 0xa043000b, 0x3c031000, 0xa4440010, 0xa0400012, + 0xa0400013, 0xac400014, 0xac400024, 0xac400028, 0xac40002c, 0xac450018, + 0x03e00008, 0xaf4301b8, 0x24020001, 0xacc40000, 0x03e00008, 0xa4e50000, + 0x03e00008, 0x24020001, 0x24020001, 0xaf400044, 0x03e00008, 0xaf400050, + 0x00803021, 0x27450180, 0x3c038000, 0x8f4201b8, 0x00431024, 0x1440fffd, + 0x00000000, 0x8f420128, 0xaca20000, 0x8cc30018, 0x240240c1, 0xa4a20008, + 0xaca30018, 0x90c4000a, 0x24020002, 0xa0a2000b, 0xa0a4000a, 0x94c20010, + 0xa4a20010, 0x90c30012, 0xa0a30012, 0x90c20013, 0xa0a20013, 0x8cc30014, + 0xaca30014, 0x8cc20024, 0xaca20024, 0x8cc30028, 0xaca30028, 0x8cc2002c, + 0x3c031000, 0xaca2002c, 0x24020001, 0xaf4301b8, 0xaf400044, 0x03e00008, + 0xaf400050, 0x27bdffe8, 0xafbf0010, 0x0e000326, 0x00000000, 0x00002021, + 0x0e00004c, 0xaf400180, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f460148, + 0x27450180, 0x3c038000, 0x00061402, 0x304700ff, 0x8f4201b8, 0x00431024, + 0x1440fffd, 0x00000000, 0x8f440140, 0x00061202, 0x304200ff, 0x00061c02, + 0xaca20004, 0x24020002, 0xa4a30008, 0x30c300ff, 0xa0a2000b, 0xaca30024, + 0x10e0000a, 0xaca40000, 0x28e20004, 0x14400005, 0x24020001, 0x24020005, + 0x54e20005, 0xa0a0000a, 0x24020001, 0x0a000816, 0xa0a2000a, 0xa0a0000a, + 0x3c021000, 0x03e00008, 0xaf4201b8, 0x03e00008, 0x00001021, 0x10c00007, + 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, 0x14c0fffb, + 0x24840004, 0x03e00008, 0x00000000, 0x0a00082a, 0x00a01021, 0xac860000, + 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, 0x00000000, + 0x00000000 }; + +static u32 bnx2_RXP_b06FwData[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_RXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_RXP_b06FwBss[(0x239c/4) + 1] = { 0x00000000 }; +static u32 bnx2_RXP_b06FwSbss[(0x14/4) + 1] = { 0x00000000 }; + +static u32 bnx2_rv2p_proc1[] = { + 0x00000008, 0xac000001, 0x0000000c, 0x2f800001, 0x00000010, 0x213f0004, + 0x00000010, 0x20bf002c, 0x00000010, 0x203f0143, 0x00000018, 0x8000fffd, + 0x00000010, 0xb1b8b017, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000, + 0x00000000, 0x2c380000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000, + 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x00000008, 0x02000002, + 0x00000010, 0x91de0000, 0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08, + 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000008, 0x2d800150, + 0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000010, 0x2c620002, + 0x00000018, 0x80000012, 0x0000000b, 0x2fdf0002, 0x0000000c, 0x1f800002, + 0x00000000, 0x2c070000, 0x00000018, 0x8000ffe6, 0x00000008, 0x02000002, + 0x0000000f, 0x42e0001c, 0x00000010, 0x91840a08, 0x00000008, 0x2c8000b0, + 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, + 0x00000000, 0x00000000, 0x00000010, 0x91de0000, 0x00000018, 0x80000004, + 0x0000000c, 0x1f800002, 0x00000000, 0x00000000, 0x00000018, 0x8000ffd9, + 0x0000000c, 0x29800002, 0x0000000c, 0x1f800002, 0x00000000, 0x2adf0000, + 0x00000008, 0x2a000005, 0x00000018, 0x8000ffd4, 0x00000008, 0x02240030, + 0x00000018, 0x00040000, 0x00000018, 0x80000015, 0x00000018, 0x80000017, + 0x00000018, 0x8000001b, 0x00000018, 0x8000004c, 0x00000018, 0x8000008c, + 0x00000018, 0x8000000f, 0x00000018, 0x8000000e, 0x00000018, 0x8000000d, + 0x00000018, 0x8000000c, 0x00000018, 0x800000c2, 0x00000018, 0x8000000a, + 0x00000018, 0x80000009, 0x00000018, 0x80000008, 0x00000018, 0x800000fd, + 0x00000018, 0x80000006, 0x00000018, 0x80000005, 0x00000018, 0x800000ff, + 0x00000018, 0x80000104, 0x00000018, 0x80000002, 0x00000018, 0x80000098, + 0x00000018, 0x80000000, 0x0000000c, 0x1f800001, 0x00000000, 0x00000000, + 0x00000018, 0x8000ffba, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001, + 0x0000000c, 0x1f800001, 0x00000008, 0x2a000002, 0x00000018, 0x8000ffb5, + 0x00000010, 0xb1a0b012, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000, + 0x00000008, 0x2c800000, 0x00000008, 0x2d000000, 0x00000010, 0x91d40000, + 0x00000008, 0x2d80011c, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, + 0x0000000f, 0x47600008, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, + 0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, + 0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000018, 0x80000013, + 0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002, 0x00000008, 0x2c800000, + 0x00000008, 0x2d000000, 0x00000010, 0x91d40000, 0x00000008, 0x2d80011c, + 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, 0x00000000, 0x0f580000, + 0x00000010, 0x91de0000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, + 0x00000000, 0x0b660000, 0x00000000, 0x0d610000, 0x00000000, 0x02620000, + 0x0000000b, 0x2fdf0002, 0x00000000, 0x309a0000, 0x00000000, 0x31040000, + 0x00000000, 0x0c961800, 0x00000009, 0x0c99ffff, 0x00000004, 0xcc993400, + 0x00000010, 0xb1963202, 0x00000008, 0x0f800000, 0x0000000c, 0x29800001, + 0x00000010, 0x00220002, 0x0000000c, 0x29520001, 0x0000000c, 0x29520000, + 0x00000008, 0x22000001, 0x0000000c, 0x1f800001, 0x00000000, 0x2adf0000, + 0x00000008, 0x2a000003, 0x00000018, 0x8000ff83, 0x00000010, 0xb1a0b01d, + 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0, + 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150, + 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000, + 0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000000, 0x00000000, + 0x00000010, 0x91de0000, 0x0000000f, 0x47600008, 0x00000000, 0x060e0000, + 0x00000010, 0x001f0000, 0x00000000, 0x0f580000, 0x00000010, 0x91de0000, + 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, 0x00000000, 0x0b670000, + 0x00000000, 0x0d620000, 0x00000000, 0x0ce71800, 0x00000009, 0x0c99ffff, + 0x00000004, 0xcc993400, 0x00000010, 0xb1963220, 0x00000008, 0x0f800000, + 0x00000018, 0x8000001e, 0x0000000f, 0x47600008, 0x0000000b, 0x2fdf0002, + 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, + 0x00000008, 0x2d80012c, 0x0000000f, 0x060e0001, 0x00000010, 0x001f0000, + 0x00000000, 0x0f580000, 0x00000010, 0x91de0000, 0x00000000, 0x0a640000, + 0x00000000, 0x0ae50000, 0x00000000, 0x0b670000, 0x00000000, 0x0d620000, + 0x00000000, 0x02630000, 0x0000000f, 0x47620010, 0x00000000, 0x0ce71800, + 0x0000000b, 0x2fdf0002, 0x00000000, 0x311a0000, 0x00000000, 0x31840000, + 0x0000000b, 0xc20000ff, 0x00000002, 0x42040000, 0x00000001, 0x31620800, + 0x0000000f, 0x020e0010, 0x00000002, 0x31620800, 0x00000009, 0x0c99ffff, + 0x00000004, 0xcc993400, 0x00000010, 0xb1963202, 0x00000008, 0x0f800000, + 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x0000000c, 0x61420006, + 0x00000008, 0x22000008, 0x00000000, 0x2adf0000, 0x00000008, 0x2a000004, + 0x00000018, 0x8000ff42, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, + 0x00000010, 0x91a0b008, 0x00000010, 0x91d40000, 0x0000000c, 0x31620018, + 0x00000008, 0x2d800001, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, + 0x00000008, 0xac000001, 0x00000018, 0x8000000e, 0x00000000, 0x0380b000, + 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c004000, 0x00000010, 0x91d40000, + 0x00000008, 0x2d800101, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, + 0x0000000c, 0x31620018, 0x00000008, 0x2d800001, 0x00000000, 0x00000000, + 0x00000010, 0x91de0000, 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c000e00, + 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000008, 0x2a000007, + 0x00000018, 0x8000ff27, 0x00000010, 0xb1a0b016, 0x0000000b, 0x2fdf0002, + 0x00000000, 0x03d80000, 0x00000000, 0x2c200000, 0x00000008, 0x2c8000b0, + 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800150, + 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800000, + 0x00000008, 0x2d000000, 0x00000008, 0x2d800108, 0x00000008, 0x07000001, + 0x00000010, 0xb5de1c00, 0x00000010, 0x2c620002, 0x00000018, 0x8000000a, + 0x0000000b, 0x2fdf0002, 0x00000000, 0x2c070000, 0x0000000c, 0x1f800001, + 0x00000010, 0x91de0000, 0x00000018, 0x8000ff11, 0x00000008, 0x2c8000b0, + 0x00000008, 0x2d000008, 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, + 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000010, 0x91de0000, + 0x00000000, 0x2adf0000, 0x00000008, 0x2a00000a, 0x00000018, 0x8000ff07, + 0x00000000, 0x82265600, 0x0000000f, 0x47220008, 0x00000009, 0x070e000f, + 0x00000008, 0x070e0008, 0x00000008, 0x02800001, 0x00000007, 0x02851c00, + 0x00000008, 0x82850001, 0x00000000, 0x02840a00, 0x00000007, 0x42851c00, + 0x00000003, 0xc3aa5200, 0x00000000, 0x03b10e00, 0x00000010, 0x001f0000, + 0x0000000f, 0x0f280007, 0x00000007, 0x4b071c00, 0x00000000, 0x00000000, + 0x0000000f, 0x0a960003, 0x00000000, 0x0a955c00, 0x00000000, 0x4a005a00, + 0x00000000, 0x0c960a00, 0x00000009, 0x0c99ffff, 0x00000008, 0x0d00ffff, + 0x00000010, 0xb1963202, 0x00000008, 0x0f800005, 0x00000010, 0x00220020, + 0x00000000, 0x02a70000, 0x00000010, 0xb1850002, 0x00000008, 0x82850200, + 0x00000000, 0x02000000, 0x00000000, 0x03a60000, 0x00000018, 0x8000004e, + 0x00000000, 0x072b0000, 0x00000001, 0x878c1c00, 0x00000000, 0x870e1e00, + 0x00000000, 0x860c1e00, 0x00000000, 0x03061e00, 0x00000010, 0xb18e0003, + 0x00000018, 0x80000047, 0x00000018, 0x8000fffa, 0x00000010, 0x918c0003, + 0x00000010, 0xb1870002, 0x00000018, 0x80000043, 0x00000010, 0x91d40000, + 0x0000000c, 0x29800001, 0x00000000, 0x2a860000, 0x00000000, 0x230c0000, + 0x00000000, 0x2b070000, 0x00000010, 0xb187000e, 0x00000008, 0x2a000008, + 0x00000018, 0x8000003b, 0x00000010, 0x91d40000, 0x00000000, 0x28d18c00, + 0x00000000, 0x2a860000, 0x00000000, 0x230c0000, 0x00000000, 0x2b070000, + 0x00000018, 0x8000fff8, 0x00000010, 0x91d40000, 0x0000000c, 0x29800001, + 0x00000000, 0x2aab0000, 0x00000000, 0xa3265600, 0x00000000, 0x2b000000, + 0x0000000c, 0x1f800001, 0x00000008, 0x2a000008, 0x00000018, 0x8000fec8, + 0x00000010, 0x91d40000, 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, + 0x00000008, 0x2a000009, 0x00000018, 0x8000fec3, 0x00000010, 0x91d40000, + 0x0000000c, 0x29800001, 0x0000000c, 0x1f800001, 0x00000000, 0x29420000, + 0x00000008, 0x2a000002, 0x00000018, 0x8000febd, 0x00000018, 0x8000febc, + 0x00000010, 0xb1bcb016, 0x0000000b, 0x2fdf0002, 0x00000000, 0x03d80000, + 0x00000000, 0x2c3c0000, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, + 0x00000010, 0x91d40000, 0x00000008, 0x2d800150, 0x00000000, 0x00000000, + 0x00000010, 0x205f0000, 0x00000008, 0x2c800000, 0x00000008, 0x2d000000, + 0x00000008, 0x2d800108, 0x00000008, 0x07000001, 0x00000010, 0xb5de1c00, + 0x00000010, 0x2c620002, 0x00000018, 0x8000000a, 0x0000000b, 0x2fdf0002, + 0x00000000, 0x2c070000, 0x0000000c, 0x1f800000, 0x00000010, 0x91de0000, + 0x00000018, 0x8000fea6, 0x00000008, 0x2c8000b0, 0x00000008, 0x2d000008, + 0x00000010, 0x91d40000, 0x00000008, 0x2d800108, 0x0000000c, 0x29800000, + 0x0000000c, 0x1f800000, 0x00000010, 0x91de0000, 0x00000000, 0x2adf0000, + 0x00000008, 0x2a000006, 0x00000018, 0x8000fe9c, 0x00000008, 0x03050004, + 0x00000006, 0x83040c00, 0x00000008, 0x02850200, 0x00000000, 0x86050c00, + 0x00000001, 0x860c0e00, 0x00000008, 0x02040004, 0x00000000, 0x02041800, + 0x00000000, 0x83871800, 0x00000018, 0x00020000 }; + +static u32 bnx2_rv2p_proc2[] = { + 0x00000000, 0x2a000000, 0x00000010, 0xb1d40000, 0x00000008, 0x02540003, + 0x00000018, 0x00040000, 0x00000018, 0x8000000a, 0x00000018, 0x8000000a, + 0x00000018, 0x8000000e, 0x00000018, 0x80000056, 0x00000018, 0x800001b9, + 0x00000018, 0x800001e1, 0x00000018, 0x8000019b, 0x00000018, 0x800001f9, + 0x00000018, 0x8000019f, 0x00000018, 0x800001a6, 0x00000018, 0x80000000, + 0x0000000c, 0x29800001, 0x00000000, 0x2a000000, 0x0000000c, 0x29800000, + 0x00000010, 0x20530000, 0x00000018, 0x8000ffee, 0x0000000c, 0x29800001, + 0x00000010, 0x91de0000, 0x00000010, 0x001f0000, 0x00000000, 0x2f80aa00, + 0x00000000, 0x2a000000, 0x00000000, 0x0d610000, 0x00000000, 0x03620000, + 0x00000000, 0x2c400000, 0x00000000, 0x02638c00, 0x00000000, 0x26460000, + 0x00000010, 0x00420002, 0x00000008, 0x02040012, 0x00000010, 0xb9060836, + 0x00000000, 0x0f580000, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, + 0x00000000, 0x0b660000, 0x00000000, 0x0c000000, 0x00000000, 0x0b800000, + 0x00000010, 0x00420009, 0x00000008, 0x0cc60012, 0x00000008, 0x0f800003, + 0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000008, 0x27110012, + 0x00000000, 0x66900000, 0x00000008, 0xa31b0012, 0x00000018, 0x80000008, + 0x00000000, 0x0cc60000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000, + 0x00000010, 0x009f0000, 0x00000000, 0x27110000, 0x00000000, 0x66900000, + 0x00000000, 0x231b0000, 0x00000010, 0xb197320e, 0x00000000, 0x25960000, + 0x00000000, 0x021b0000, 0x00000010, 0x001f0000, 0x00000008, 0x0f800003, + 0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000000, 0x22c50800, + 0x00000010, 0x009f0000, 0x00000000, 0x27002200, 0x00000000, 0x26802000, + 0x00000000, 0x231b0000, 0x0000000c, 0x69520001, 0x00000018, 0x8000fff3, + 0x00000010, 0x01130002, 0x00000010, 0xb1980003, 0x00000010, 0x001f0000, + 0x00000008, 0x0f800004, 0x00000008, 0x22000003, 0x00000008, 0x2c80000c, + 0x00000008, 0x2d00000c, 0x00000010, 0x009f0000, 0x00000000, 0x25960000, + 0x0000000c, 0x29800000, 0x00000000, 0x32140000, 0x00000000, 0x32950000, + 0x00000000, 0x33160000, 0x00000000, 0x31e32e00, 0x00000008, 0x2d800010, + 0x00000010, 0x20530000, 0x00000018, 0x8000ffac, 0x00000000, 0x23000000, + 0x00000000, 0x25e60000, 0x00000008, 0x2200000b, 0x0000000c, 0x69520000, + 0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000018, 0x8000ffa5, + 0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, + 0x00000010, 0x001f0000, 0x00000000, 0x02700000, 0x00000000, 0x0d620000, + 0x00000000, 0xbb630800, 0x00000000, 0x2a000000, 0x00000009, 0x076000ff, + 0x0000000f, 0x2c0e0007, 0x00000008, 0x2c800000, 0x00000008, 0x2d000064, + 0x00000008, 0x2d80011c, 0x00000009, 0x06420002, 0x0000000c, 0x61420001, + 0x00000000, 0x0f400000, 0x00000000, 0x02d08c00, 0x00000000, 0x23000000, + 0x00000004, 0x826da000, 0x00000000, 0x8304a000, 0x00000000, 0x22c50c00, + 0x00000000, 0x03760000, 0x00000004, 0x83860a00, 0x00000000, 0x83870c00, + 0x00000010, 0x91de0000, 0x00000000, 0x037c0000, 0x00000000, 0x837b0c00, + 0x00000001, 0x83060e00, 0x00000000, 0x83870c00, 0x00000000, 0x82850e00, + 0x00000010, 0xb1860016, 0x0000000f, 0x47610018, 0x00000000, 0x068e0000, + 0x0000000f, 0x47670010, 0x0000000f, 0x47e20010, 0x00000000, 0x870e1e00, + 0x00000010, 0xb70e1a10, 0x00000010, 0x0ce7000e, 0x00000008, 0x22000009, + 0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400, + 0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004, + 0x00000018, 0x8000023f, 0x00000000, 0x37ed0000, 0x0000000c, 0x73e7001a, + 0x00000010, 0x20530000, 0x00000008, 0x22000008, 0x0000000c, 0x61420004, + 0x00000000, 0x02f60000, 0x00000004, 0x82840a00, 0x00000010, 0xb1840a2b, + 0x00000010, 0x2d67000a, 0x00000010, 0xb96d0804, 0x00000004, 0xb6ed0a00, + 0x00000000, 0x37ed0000, 0x00000018, 0x80000029, 0x0000000c, 0x61420000, + 0x00000000, 0x37040000, 0x00000000, 0x37850000, 0x0000000c, 0x33e7001a, + 0x00000018, 0x80000024, 0x00000010, 0xb96d0809, 0x00000004, 0xb6ed0a00, + 0x00000000, 0x036d0000, 0x00000004, 0xb76e0c00, 0x00000010, 0x91ee0c1f, + 0x0000000c, 0x73e7001a, 0x00000004, 0xb6ef0c00, 0x00000000, 0x37ed0000, + 0x00000018, 0x8000001b, 0x0000000c, 0x61420000, 0x00000010, 0xb7ee0a05, + 0x00000010, 0xb96f0815, 0x00000003, 0xb76e0800, 0x00000004, 0xb7ef0a00, + 0x00000018, 0x80000015, 0x00000010, 0x0ce7000c, 0x00000008, 0x22000009, + 0x00000000, 0x286d0000, 0x0000000f, 0x65680010, 0x00000003, 0xf66c9400, + 0x00000010, 0xb972a003, 0x0000000c, 0x73e70019, 0x0000000c, 0x21420004, + 0x00000018, 0x80000215, 0x00000010, 0x20530000, 0x00000008, 0x22000008, + 0x0000000c, 0x61420004, 0x00000000, 0x37040000, 0x00000000, 0x37850000, + 0x00000000, 0x036d0000, 0x00000003, 0xb8f10c00, 0x00000018, 0x80000004, + 0x00000000, 0x02840000, 0x00000002, 0x21421800, 0x0000000c, 0x61420000, + 0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff, + 0x00000000, 0x23000000, 0x00000010, 0xb1840a3d, 0x00000010, 0x01420002, + 0x00000004, 0xb8f10a00, 0x00000003, 0x83760a00, 0x00000010, 0xb8040c39, + 0x00000010, 0xb7e6080a, 0x00000000, 0x0a640000, 0x00000000, 0x0ae50000, + 0x00000009, 0x0c68ffff, 0x00000009, 0x0b67ffff, 0x00000000, 0x0be60000, + 0x00000000, 0x0c840000, 0x00000010, 0xb197320c, 0x00000008, 0x0f800002, + 0x00000018, 0x8000000a, 0x00000000, 0x0a6a0000, 0x00000000, 0x0aeb0000, + 0x00000000, 0x0c000000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0be90000, + 0x00000000, 0x0c840000, 0x00000010, 0xb1973203, 0x00000008, 0x0f800002, + 0x00000018, 0x80000001, 0x00000010, 0x001f0000, 0x00000000, 0x0c860000, + 0x00000000, 0x06980000, 0x00000008, 0x0f800003, 0x00000000, 0x00000000, + 0x00000010, 0x009f0000, 0x00000010, 0xb1973210, 0x00000000, 0x231b0000, + 0x00000000, 0x02043600, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, + 0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000, + 0x0000000c, 0x29000000, 0x00000018, 0x800001de, 0x00000000, 0x06980000, + 0x00000010, 0x20530000, 0x00000000, 0x22c58c00, 0x00000010, 0x001f0000, + 0x00000008, 0x0f800003, 0x00000018, 0x8000fff0, 0x00000000, 0x02043600, + 0x00000000, 0x231b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, + 0x00000009, 0x2607ffff, 0x00000000, 0x27111a00, 0x00000000, 0x66900000, + 0x0000000c, 0x29000000, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, + 0x00000000, 0x32140000, 0x00000000, 0x32950000, 0x00000005, 0x73e72c00, + 0x00000005, 0x74683000, 0x00000000, 0x33170000, 0x00000018, 0x80000138, + 0x00000010, 0x91c60004, 0x00000008, 0x07000004, 0x00000010, 0xb1c41c02, + 0x00000010, 0x91840a04, 0x00000018, 0x800001c3, 0x00000010, 0x20530000, + 0x00000000, 0x22c58c00, 0x00000010, 0xb1840a8e, 0x0000000c, 0x21420006, + 0x00000010, 0x0ce7001a, 0x0000000f, 0x43680010, 0x00000000, 0x03f30c00, + 0x00000010, 0x91870850, 0x0000000f, 0x46ec0010, 0x00000010, 0xb68d0c4e, + 0x00000000, 0x838d0c00, 0x00000000, 0xa3050800, 0x00000001, 0xa3460e00, + 0x00000000, 0x02048c00, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, + 0x00000010, 0x001f0000, 0x00000008, 0x22000008, 0x00000003, 0x8384a000, + 0x0000000f, 0x65870010, 0x00000009, 0x2607ffff, 0x00000000, 0x27750c00, + 0x00000000, 0x66f40000, 0x0000000c, 0x29000000, 0x00000018, 0x800001aa, + 0x00000000, 0x03068c00, 0x00000003, 0xf4680c00, 0x00000010, 0x20530000, + 0x00000000, 0x22c58c00, 0x00000018, 0x8000ffe5, 0x00000000, 0x39760000, + 0x00000000, 0x39840000, 0x0000000c, 0x33e70019, 0x00000010, 0x001f0000, + 0x00000000, 0x031e0000, 0x00000000, 0x0760fe00, 0x0000000f, 0x0f0e0007, + 0x00000000, 0x83850800, 0x00000000, 0x0a7d0000, 0x00000000, 0x0afe0000, + 0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000, 0x00000000, 0x0c000000, + 0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003, + 0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff, + 0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010, + 0x00000002, 0x33e70e00, 0x00000000, 0x28f30000, 0x00000010, 0x009f0000, + 0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, + 0x00000008, 0x22000006, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000, + 0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, + 0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000, + 0x0000000c, 0x29000000, 0x00000018, 0x8000017e, 0x00000003, 0xf4683600, + 0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400, + 0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004, + 0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000, + 0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000, + 0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000, + 0x00000000, 0x22c53600, 0x00000018, 0x8000ffac, 0x00000010, 0x001f0000, + 0x00000000, 0x031e0000, 0x00000000, 0x83850800, 0x00000009, 0x076000ff, + 0x0000000f, 0x0f0e0007, 0x00000000, 0x0c000000, 0x00000000, 0x0a7d0000, + 0x00000000, 0x0afe0000, 0x00000000, 0x0b7f0000, 0x00000000, 0x0d7a0000, + 0x00000000, 0x0bfc0000, 0x00000000, 0x0c970e00, 0x00000008, 0x0f800003, + 0x0000000f, 0x47670010, 0x00000008, 0x070e0001, 0x0000000b, 0xc38000ff, + 0x00000002, 0x43870000, 0x00000001, 0x33e70e00, 0x0000000f, 0x038e0010, + 0x00000002, 0x33e70e00, 0x00000000, 0x39840000, 0x00000003, 0xb9720800, + 0x00000000, 0x28f30000, 0x0000000f, 0x65680010, 0x00000010, 0x009f0000, + 0x00000000, 0x02043600, 0x00000010, 0x91840a02, 0x00000002, 0x21421800, + 0x00000008, 0x22000007, 0x00000000, 0x231b0000, 0x00000000, 0x23ff0000, + 0x00000000, 0x241b0000, 0x00000003, 0x8384a000, 0x0000000f, 0x65870010, + 0x00000009, 0x2607ffff, 0x00000000, 0x27110000, 0x00000000, 0x26900000, + 0x0000000c, 0x29000000, 0x00000018, 0x80000145, 0x00000003, 0xf4683600, + 0x00000000, 0x3a100000, 0x00000000, 0x3a910000, 0x00000003, 0xf66c2400, + 0x00000010, 0x001f0000, 0x00000010, 0xb1923604, 0x00000008, 0x0f800004, + 0x00000000, 0x00000000, 0x00000010, 0x009f0000, 0x00000000, 0x3e170000, + 0x00000000, 0x3e940000, 0x00000000, 0x3f150000, 0x00000000, 0x3f960000, + 0x00000010, 0x001f0000, 0x00000000, 0x0f060000, 0x00000010, 0x20530000, + 0x00000000, 0x22c53600, 0x00000018, 0x8000ff73, 0x00000010, 0x0ce70005, + 0x00000008, 0x2c80000c, 0x00000008, 0x2d000070, 0x00000008, 0x2d800010, + 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000018, 0x8000011d, + 0x00000000, 0x2c1e0000, 0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010, + 0x00000008, 0x2d800048, 0x00000000, 0x00000000, 0x00000010, 0x91de0000, + 0x00000018, 0x8000fe5d, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000, + 0x00000010, 0x001f0000, 0x00000000, 0x0f008000, 0x00000008, 0x0f800007, + 0x00000018, 0x80000006, 0x0000000c, 0x29800001, 0x00000000, 0x2a000000, + 0x00000010, 0x001f0000, 0x0000000f, 0x0f470007, 0x00000008, 0x0f800008, + 0x00000018, 0x80000119, 0x00000010, 0x20530000, 0x00000018, 0x8000fe4f, + 0x0000000c, 0x29800001, 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, + 0x00000000, 0x2a000000, 0x00000009, 0x0261ffff, 0x0000000d, 0x70e10001, + 0x00000018, 0x80000101, 0x00000000, 0x2c400000, 0x00000008, 0x2c8000c4, + 0x00000008, 0x2d00001c, 0x00000008, 0x2d800001, 0x00000005, 0x70e10800, + 0x00000010, 0x91de0000, 0x00000018, 0x8000fe41, 0x0000000c, 0x29800001, + 0x00000010, 0x91de0000, 0x00000000, 0x2fd50000, 0x00000010, 0x001f0000, + 0x00000000, 0x02700000, 0x00000000, 0x0d620000, 0x00000000, 0xbb630800, + 0x00000000, 0x2a000000, 0x00000000, 0x0f400000, 0x00000000, 0x2c400000, + 0x0000000c, 0x73e7001b, 0x00000010, 0x0ce7000e, 0x00000000, 0x286d0000, + 0x0000000f, 0x65ed0010, 0x00000009, 0x266dffff, 0x00000018, 0x80000069, + 0x00000008, 0x02000004, 0x00000010, 0x91c40803, 0x00000018, 0x800000f6, + 0x00000010, 0x20530000, 0x00000018, 0x800000e5, 0x00000008, 0x2c8000b8, + 0x00000008, 0x2d000010, 0x00000008, 0x2d800048, 0x00000018, 0x80000005, + 0x00000008, 0x2c8000c4, 0x00000008, 0x2d00001c, 0x00000008, 0x2d800001, + 0x00000000, 0x00000000, 0x00000010, 0x205f0000, 0x00000008, 0x2c800048, + 0x00000008, 0x2d000068, 0x00000008, 0x2d800104, 0x00000000, 0x00000000, + 0x00000010, 0x91de0000, 0x00000000, 0x27f60000, 0x00000010, 0xb87a9e04, + 0x00000008, 0x2200000d, 0x00000018, 0x800000e2, 0x00000010, 0x20530000, + 0x00000018, 0x8000fe18, 0x0000000c, 0x29800001, 0x00000010, 0x91de0000, + 0x00000000, 0x2fd50000, 0x00000010, 0x001f0000, 0x00000000, 0x02700000, + 0x00000000, 0x0d620000, 0x00000000, 0xbb630800, 0x00000000, 0x2a000000, + 0x00000010, 0x0e670011, 0x00000000, 0x286d0000, 0x0000000f, 0x65ed0010, + 0x00000009, 0x266dffff, 0x00000004, 0xb8f1a000, 0x00000000, 0x0f400000, + 0x0000000c, 0x73e7001c, 0x00000018, 0x80000040, 0x00000008, 0x02000004, + 0x00000010, 0x91c40802, 0x00000018, 0x800000cd, 0x00000000, 0x2c1e0000, + 0x00000008, 0x2c8000b8, 0x00000008, 0x2d000010, 0x00000008, 0x2d800048, + 0x00000010, 0x20530000, 0x00000010, 0x91de0000, 0x00000018, 0x8000fdfe, + 0x0000000c, 0x29800001, 0x00000000, 0x03550000, 0x00000000, 0x06460000, + 0x00000000, 0x03d60000, 0x00000000, 0x2a000000, 0x0000000f, 0x0f480007, + 0x00000010, 0xb18c0027, 0x0000000f, 0x47420008, 0x00000009, 0x070e000f, + 0x00000008, 0x070e0008, 0x00000010, 0x001f0000, 0x00000008, 0x09000001, + 0x00000007, 0x09121c00, 0x00000003, 0xcbca9200, 0x00000000, 0x0b97a200, + 0x00000007, 0x4b171c00, 0x0000000f, 0x0a960003, 0x00000000, 0x0a959c00, + 0x00000000, 0x4a009a00, 0x00000008, 0x82120001, 0x00000001, 0x0c170800, + 0x00000000, 0x02180000, 0x00000000, 0x0c971800, 0x00000008, 0x0d00ffff, + 0x00000008, 0x0f800006, 0x0000000c, 0x29000000, 0x00000008, 0x22000001, + 0x00000000, 0x22c50c00, 0x00000010, 0x009f0000, 0x00000010, 0xb197320b, + 0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000, + 0x00000018, 0x800000a4, 0x00000000, 0x02180000, 0x00000010, 0x20530000, + 0x00000000, 0x22c53600, 0x00000010, 0x001f0000, 0x00000008, 0x0f800006, + 0x00000018, 0x8000fff5, 0x00000010, 0x91870002, 0x00000008, 0x2200000a, + 0x00000000, 0x231b0000, 0x00000000, 0x27110800, 0x00000000, 0x66900000, + 0x00000018, 0x80000098, 0x00000008, 0x0200000a, 0x00000010, 0x91c40804, + 0x00000010, 0x02c20003, 0x00000010, 0x001f0000, 0x00000008, 0x0f800008, + 0x00000010, 0x20530000, 0x00000018, 0x8000fdc9, 0x00000000, 0x06820000, + 0x00000010, 0x001f0000, 0x00000010, 0x0ce70028, 0x00000000, 0x03720000, + 0x00000000, 0xa8760c00, 0x00000000, 0x0cf60000, 0x00000010, 0xb8723224, + 0x00000000, 0x03440000, 0x00000008, 0x22000010, 0x00000000, 0x03ca0000, + 0x0000000f, 0x65680010, 0x00000000, 0x0bcf0000, 0x00000000, 0x27f20000, + 0x00000010, 0xb7ef3203, 0x0000000c, 0x21420004, 0x0000000c, 0x73e70019, + 0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x8000007e, + 0x00000004, 0xb9723200, 0x00000010, 0x20530000, 0x00000000, 0x22060000, + 0x0000000c, 0x61420004, 0x00000000, 0x25070000, 0x00000000, 0x27970000, + 0x00000000, 0x290e0000, 0x00000010, 0x0ce70010, 0x00000010, 0xb873320f, + 0x0000000f, 0x436c0010, 0x00000000, 0x03f30c00, 0x00000000, 0x03f30000, + 0x00000000, 0x83990e00, 0x00000001, 0x83860e00, 0x00000000, 0x83060e00, + 0x00000003, 0xf66c0c00, 0x00000000, 0x39f30e00, 0x00000000, 0x3af50e00, + 0x00000000, 0x7a740000, 0x0000000f, 0x43680010, 0x00000001, 0x83860e00, + 0x00000000, 0x83060e00, 0x00000003, 0xf4680c00, 0x00000000, 0x286d0000, + 0x00000000, 0x03690000, 0x00000010, 0xb1f60c54, 0x00000000, 0x0a6a0000, + 0x00000000, 0x0aeb0000, 0x00000009, 0x0b6cffff, 0x00000000, 0x0c000000, + 0x00000000, 0x0be90000, 0x00000003, 0x8cf6a000, 0x0000000c, 0x09800002, + 0x00000010, 0x009f0000, 0x00000010, 0xb8173209, 0x00000000, 0x35140000, + 0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34970000, + 0x00000004, 0xb8f12e00, 0x00000010, 0x001f0000, 0x00000008, 0x0f800004, + 0x00000018, 0x8000fff7, 0x00000000, 0x03e90000, 0x00000010, 0xb8f6a01a, + 0x00000010, 0x20130019, 0x00000010, 0xb1f10e18, 0x00000000, 0x83973200, + 0x00000000, 0x38700e00, 0x00000000, 0xbb760e00, 0x00000000, 0x37d00000, + 0x0000000c, 0x73e7001a, 0x00000003, 0xb8f1a000, 0x00000000, 0x32140000, + 0x00000000, 0x32950000, 0x00000005, 0x73e72c00, 0x00000000, 0x33190000, + 0x00000005, 0x74680000, 0x00000010, 0x0ce7000d, 0x00000008, 0x22000009, + 0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x0000000c, 0x73e70019, + 0x0000000f, 0x65680010, 0x0000000c, 0x21420004, 0x00000018, 0x8000003c, + 0x00000010, 0x20530000, 0x0000000c, 0x61420004, 0x00000000, 0x290e0000, + 0x00000018, 0x80000002, 0x00000010, 0x91973206, 0x00000000, 0x35140000, + 0x00000000, 0x35950000, 0x00000005, 0x766c2c00, 0x00000000, 0x34990000, + 0x00000004, 0xb8f13200, 0x00000000, 0x83690c00, 0x00000010, 0xb1860013, + 0x00000000, 0x28e90000, 0x00000008, 0x22000004, 0x00000000, 0x23ec0000, + 0x00000000, 0x03690000, 0x00000010, 0xb8660c07, 0x00000009, 0x036cffff, + 0x00000000, 0x326a0000, 0x00000000, 0x32eb0000, 0x00000005, 0x73e70c00, + 0x00000000, 0x33690000, 0x00000005, 0x74680000, 0x0000000c, 0x73e7001c, + 0x00000000, 0x03690000, 0x00000010, 0xb1f60c12, 0x00000010, 0xb1d00c11, + 0x0000000c, 0x21420005, 0x0000000c, 0x33e7001c, 0x00000018, 0x8000000e, + 0x00000010, 0x2e67000d, 0x00000000, 0x03690000, 0x00000010, 0xb1f60c0b, + 0x00000010, 0xb1d00c0a, 0x00000000, 0x03440000, 0x00000008, 0x2200000c, + 0x00000000, 0x07520000, 0x00000000, 0x29000000, 0x00000018, 0x80000015, + 0x0000000c, 0x33e7001c, 0x00000010, 0x20530000, 0x00000000, 0x22060000, + 0x00000000, 0x290e0000, 0x00000018, 0x000d0000, 0x00000000, 0x06820000, + 0x00000010, 0x2de7000d, 0x00000010, 0x0ce7000c, 0x00000000, 0x27f20000, + 0x00000010, 0xb96d9e0a, 0x00000000, 0xa86d9e00, 0x00000009, 0x0361ffff, + 0x00000010, 0xb7500c07, 0x00000008, 0x2200000f, 0x0000000f, 0x65680010, + 0x00000000, 0x29000000, 0x00000018, 0x80000004, 0x0000000c, 0x33e7001b, + 0x00000010, 0x20530000, 0x00000018, 0x000d0000, 0x00000000, 0x2b820000, + 0x00000010, 0x20d2002f, 0x00000010, 0x0052002e, 0x00000009, 0x054e0007, + 0x00000010, 0xb18a002c, 0x00000000, 0x050a8c00, 0x00000008, 0x850a0008, + 0x00000010, 0x918a0029, 0x00000003, 0xc5008800, 0x00000008, 0xa3460001, + 0x00000010, 0xb1c60007, 0x00000008, 0x22000001, 0x0000000c, 0x29800000, + 0x00000010, 0x20530000, 0x00000000, 0x274e8c00, 0x00000000, 0x66cd0000, + 0x00000000, 0x22c58c00, 0x00000008, 0x22000014, 0x00000003, 0x22c58e00, + 0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00, + 0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000, + 0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x0000000c, 0x69520000, + 0x0000000c, 0x29800000, 0x00000010, 0x20530000, 0x00000003, 0x22c58e00, + 0x00000003, 0x23c58e00, 0x00000003, 0x22c58e00, 0x00000003, 0x26cd9e00, + 0x00000003, 0x27cd9e00, 0x00000003, 0x26cd9e00, 0x00000003, 0x274ea000, + 0x00000003, 0x284ea000, 0x00000003, 0x274ea000, 0x00000000, 0xa2c58c00, + 0x00000000, 0xa74e8c00, 0x00000000, 0xe6cd0000, 0x0000000f, 0x620a0010, + 0x00000008, 0x23460001, 0x0000000c, 0x29800000, 0x00000010, 0x20530000, + 0x0000000c, 0x29520000, 0x00000018, 0x80000002, 0x0000000c, 0x29800000, + 0x00000018, 0x00570000 }; + +static int bnx2_TPAT_b06FwReleaseMajor = 0x0; +static int bnx2_TPAT_b06FwReleaseMinor = 0x0; +static int bnx2_TPAT_b06FwReleaseFix = 0x0; +static u32 bnx2_TPAT_b06FwStartAddr = 0x08000858; +static u32 bnx2_TPAT_b06FwTextAddr = 0x08000800; +static int bnx2_TPAT_b06FwTextLen = 0x1314; +static u32 bnx2_TPAT_b06FwDataAddr = 0x08001b40; +static int bnx2_TPAT_b06FwDataLen = 0x0; +static u32 bnx2_TPAT_b06FwRodataAddr = 0x00000000; +static int bnx2_TPAT_b06FwRodataLen = 0x0; +static u32 bnx2_TPAT_b06FwBssAddr = 0x08001b90; +static int bnx2_TPAT_b06FwBssLen = 0x80; +static u32 bnx2_TPAT_b06FwSbssAddr = 0x08001b40; +static int bnx2_TPAT_b06FwSbssLen = 0x48; + +static u32 bnx2_TPAT_b06FwText[(0x1314/4) + 1] = { + 0x0a000216, 0x00000000, 0x00000000, 0x0000000d, 0x74706174, 0x20302e36, + 0x2e390000, 0x00060901, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x10000003, + 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24421b40, 0x3c030800, + 0x24631c10, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, + 0x37bd3ffc, 0x03a0f021, 0x3c100800, 0x26100858, 0x3c1c0800, 0x279c1b40, + 0x0e00051f, 0x00000000, 0x0000000d, 0x8f820024, 0x27bdffe8, 0xafbf0014, + 0x10400004, 0xafb00010, 0x0000000d, 0x00000000, 0x2400015f, 0x8f82001c, + 0x8c450008, 0x24030800, 0xaf430178, 0x97430104, 0x3c020008, 0xaf420140, + 0x8f820034, 0x30420001, 0x10400006, 0x3070ffff, 0x24020002, 0x2603fffe, + 0xa7420146, 0x0a000246, 0xa7430148, 0xa7400146, 0x8f850034, 0x30a20020, + 0x0002102b, 0x00021023, 0x30460009, 0x30a30c00, 0x24020400, 0x14620002, + 0x34c40001, 0x34c40005, 0xa744014a, 0x3c020800, 0x8c440820, 0x3c030048, + 0x24020002, 0x00832025, 0x30a30006, 0x1062000d, 0x2c620003, 0x50400005, + 0x24020004, 0x10600012, 0x3c020001, 0x0a000271, 0x00000000, 0x10620007, + 0x24020006, 0x1462000f, 0x3c020111, 0x0a000269, 0x00821025, 0x0a000268, + 0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030, + 0x0a000271, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x8f830030, 0x1060003f, 0x3c048000, + 0x8f421000, 0x00441024, 0x1040fffd, 0x00000000, 0x10600039, 0x00000000, + 0x8f421000, 0x3c030020, 0x00431024, 0x10400034, 0x00000000, 0x97421014, + 0x14400031, 0x00000000, 0x97421008, 0x8f84001c, 0x24420006, 0x00024082, + 0x00081880, 0x00643821, 0x8ce50000, 0x30430003, 0x30420001, 0x10400004, + 0x00000000, 0x0000000d, 0x0a0002b0, 0x00081080, 0x5460000f, 0x30a5ffff, + 0x3c06ffff, 0x00a62824, 0x0005182b, 0x00a61026, 0x0002102b, 0x00621824, + 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x240001fc, 0x8ce20000, + 0x0a0002af, 0x00462825, 0x0005182b, 0x38a2ffff, 0x0002102b, 0x00621824, + 0x10600004, 0x00000000, 0x0000000d, 0x00000000, 0x24000206, 0x8ce20000, + 0x3445ffff, 0x00081080, 0x00441021, 0x3c030800, 0xac450000, 0x8c620840, + 0x24420001, 0xac620840, 0x8f820008, 0x10400003, 0x00000000, 0x0e000660, + 0x00000000, 0x8f840028, 0x02002821, 0x24820008, 0x30421fff, 0x24434000, + 0x0343d821, 0x30a30007, 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, + 0x24a20007, 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, + 0x0064102b, 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, + 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, 0x03421821, 0x3c021000, + 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, 0x27bd0018, 0x8f820024, + 0x27bdffe8, 0xafbf0014, 0x10400004, 0xafb00010, 0x0000000d, 0x00000000, + 0x24000249, 0x8f85001c, 0x24020001, 0xaf820024, 0x8ca70008, 0xa3800023, + 0x8f620004, 0x3c100800, 0x26041b90, 0x00021402, 0xa3820010, 0x304600ff, + 0x24c60005, 0x0e00064a, 0x00063082, 0x8f640004, 0x8f430108, 0x3c021000, + 0x00621824, 0xa7840020, 0x10600008, 0x00000000, 0x97420104, 0x93830023, + 0x2442ffec, 0x34630002, 0xa3830023, 0x0a000304, 0x3045ffff, 0x97420104, + 0x2442fff0, 0x3045ffff, 0x8f620004, 0x3042ffff, 0x2c420013, 0x14400004, + 0x00000000, 0x93820023, 0x34420001, 0xa3820023, 0x93830023, 0x24020001, + 0x10620009, 0x28620002, 0x14400014, 0x24020002, 0x10620012, 0x24020003, + 0x1062000a, 0x00000000, 0x0a000325, 0x00000000, 0x8f82001c, 0x8c43000c, + 0x3c04ffff, 0x00641824, 0x00651825, 0x0a000325, 0xac43000c, 0x8f82001c, + 0x8c430010, 0x3c04ffff, 0x00641824, 0x00651825, 0xac430010, 0x8f620004, + 0x3042ffff, 0x24420002, 0x00021083, 0xa3820038, 0x304500ff, 0x8f82001c, + 0x3c04ffff, 0x00052880, 0x00a22821, 0x8ca70000, 0x97820020, 0x97430104, + 0x00e42024, 0x24420002, 0x00621823, 0x00833825, 0xaca70000, 0x93840038, + 0x26061b90, 0x00041080, 0x00461021, 0x90430000, 0x3063000f, 0x00832021, + 0xa3840022, 0x308200ff, 0x3c04fff6, 0x24420003, 0x00021080, 0x00461021, + 0x8c450000, 0x93830022, 0x8f82001c, 0x3484ffff, 0x00a43824, 0x00031880, + 0x00621821, 0xaf850000, 0xac67000c, 0x93820022, 0x93830022, 0x8f84001c, + 0x24420003, 0x00021080, 0x00461021, 0x24630004, 0x00031880, 0xac470000, + 0x93820022, 0x00661821, 0x94670002, 0x00021080, 0x00441021, 0xac670000, + 0x24030010, 0xac470010, 0xa7430140, 0x24030002, 0xa7400142, 0xa7400144, + 0xa7430146, 0x97420104, 0x8f840034, 0x24030001, 0x2442fffe, 0x30840006, + 0xa7420148, 0x24020002, 0xa743014a, 0x1082000d, 0x2c820003, 0x10400005, + 0x24020004, 0x10800011, 0x3c020009, 0x0a000383, 0x00000000, 0x10820007, + 0x24020006, 0x1482000d, 0x3c020119, 0x0a00037d, 0x24030001, 0x0a00037c, + 0x3c020109, 0x3c020019, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000383, + 0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x93820010, 0x24030008, 0x8f840030, 0x24420002, 0x30420007, + 0x00621823, 0x30630007, 0xaf83000c, 0x10800005, 0x3c038000, 0x8f421000, + 0x00431024, 0x1040fffd, 0x00000000, 0x8f820028, 0xaf820018, 0x24420010, + 0x30421fff, 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, + 0x3063ffff, 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, + 0x8f840004, 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, + 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, + 0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, + 0x03e00008, 0x27bd0018, 0x8f820024, 0x27bdffe8, 0xafbf0014, 0x14400004, + 0xafb00010, 0x0000000d, 0x00000000, 0x240002db, 0x8f620004, 0x04410009, + 0x3c050800, 0x93820022, 0x8f830000, 0x24a41b90, 0xaf800024, 0x24420003, + 0x00021080, 0x00441021, 0xac430000, 0x93820038, 0x24a51b90, 0x93860010, + 0x3c040001, 0x27700008, 0x24420001, 0x00021080, 0x00451021, 0x8c430000, + 0x24c60005, 0x00063082, 0x00641821, 0x02002021, 0x0e00064a, 0xac430000, + 0x93840022, 0x3c057fff, 0x8f620004, 0x00042080, 0x00902021, 0x8c830004, + 0x34a5ffff, 0x00451024, 0x00621821, 0xac830004, 0x93850038, 0x3c07ffff, + 0x93840010, 0x00052880, 0x00b02821, 0x8ca30000, 0x97420104, 0x97860020, + 0x00671824, 0x00441021, 0x00461023, 0x3042ffff, 0x00621825, 0xaca30000, + 0x93830023, 0x24020001, 0x10620009, 0x28620002, 0x1440001a, 0x24020002, + 0x10620018, 0x24020003, 0x1062000d, 0x00000000, 0x0a000411, 0x00000000, + 0x93820010, 0x97430104, 0x8e04000c, 0x00621821, 0x2463fff2, 0x3063ffff, + 0x00872024, 0x00832025, 0x0a000411, 0xae04000c, 0x93820010, 0x97430104, + 0x8e040010, 0x00621821, 0x2463ffee, 0x3063ffff, 0x00872024, 0x00832025, + 0xae040010, 0x9783000e, 0x8f840034, 0x2402000a, 0xa7420140, 0xa7430142, + 0x93820010, 0xa7420144, 0xa7400146, 0x97430104, 0x30840006, 0x24020001, + 0xa7430148, 0xa742014a, 0x24020002, 0x1082000d, 0x2c820003, 0x10400005, + 0x24020004, 0x10800011, 0x3c020041, 0x0a000437, 0x00000000, 0x10820007, + 0x24020006, 0x1482000d, 0x3c020151, 0x0a000431, 0x24030001, 0x0a000430, + 0x3c020141, 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a000437, + 0x00000000, 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x8f820030, 0x93840010, 0x8f850028, 0x10400005, 0x3c038000, + 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x2483000a, 0x30620007, + 0x10400002, 0x24620007, 0x304303f8, 0x00a31021, 0x30421fff, 0xaf850018, + 0xaf820028, 0xaf420084, 0x97430104, 0x24424000, 0x0342d821, 0x3063ffff, + 0x30620007, 0x10400002, 0x24620007, 0x3043fff8, 0x8f820044, 0x8f840004, + 0x00431821, 0xaf82002c, 0x0064102b, 0xaf830044, 0x14400002, 0x00641023, + 0xaf820044, 0x8f840044, 0x34028000, 0x8fbf0014, 0x8fb00010, 0x00821021, + 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0xaf420178, 0x03e00008, + 0x27bd0018, 0x3c026000, 0x8c444448, 0x3c030800, 0xac64082c, 0x8f620000, + 0x97430104, 0x3c048000, 0x3046ffff, 0x3067ffff, 0x8f420178, 0x00441024, + 0x1440fffd, 0x2402000a, 0x30c30007, 0xa7420140, 0x24020008, 0x00431023, + 0x30420007, 0x24c3fffe, 0xa7420142, 0xa7430144, 0xa7400146, 0xa7470148, + 0x8f420108, 0x3c036000, 0x8f850034, 0x30420020, 0x0002102b, 0x00021023, + 0x30420009, 0x34420001, 0xa742014a, 0x8c644448, 0x3c020800, 0x30a50006, + 0xac440830, 0x24020002, 0x10a2000d, 0x2ca20003, 0x10400005, 0x24020004, + 0x10a00011, 0x3c020041, 0x0a0004a8, 0x00000000, 0x10a20007, 0x24020006, + 0x14a2000d, 0x3c020151, 0x0a0004a2, 0x24030001, 0x0a0004a1, 0x3c020141, + 0x3c020051, 0x24030001, 0xaf421000, 0xaf830030, 0x0a0004a8, 0x00000000, + 0xaf421000, 0xaf800030, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x8f820030, 0x24c30008, 0x10400006, 0x30e6ffff, 0x3c048000, 0x8f421000, + 0x00441024, 0x1040fffd, 0x00000000, 0x3c026000, 0x8c444448, 0x3065ffff, + 0x3c020800, 0x30a30007, 0x10600003, 0xac440834, 0x24a20007, 0x3045fff8, + 0x8f840028, 0x00851021, 0x30421fff, 0x24434000, 0x0343d821, 0x30c30007, + 0xaf840018, 0xaf820028, 0xaf420084, 0x10600002, 0x24c20007, 0x3046fff8, + 0x8f820044, 0x8f840004, 0x00461821, 0xaf82002c, 0x0064102b, 0xaf830044, + 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, 0x3c030800, + 0x8c650844, 0x00821021, 0x03421821, 0xaf83001c, 0xaf440080, 0x10a00006, + 0x2402000e, 0x93830043, 0x14620004, 0x3c021000, 0x2402043f, 0xa7420148, + 0x3c021000, 0x3c036000, 0xaf420178, 0x8c644448, 0x3c020800, 0x03e00008, + 0xac440838, 0x8f820034, 0x30424000, 0x10400005, 0x24020800, 0x0000000d, + 0x00000000, 0x24000405, 0x24020800, 0xaf420178, 0x97440104, 0x3c030008, + 0xaf430140, 0x8f820034, 0x30420001, 0x10400006, 0x3085ffff, 0x24020002, + 0x24a3fffe, 0xa7420146, 0x0a0004ff, 0xa7430148, 0xa7400146, 0x8f840028, + 0x2402000d, 0xa742014a, 0x24830008, 0x30631fff, 0x24624000, 0x0342d821, + 0x30a20007, 0xaf840018, 0xaf830028, 0xaf430084, 0x10400002, 0x24a20007, + 0x3045fff8, 0x8f820044, 0x8f840004, 0x00451821, 0xaf82002c, 0x0064102b, + 0xaf830044, 0x14400002, 0x00641023, 0xaf820044, 0x8f840044, 0x34028000, + 0x00821021, 0x03421821, 0x3c021000, 0xaf83001c, 0xaf440080, 0x03e00008, + 0xaf420178, 0x27bdffe8, 0x3c046008, 0xafbf0014, 0xafb00010, 0x8c825000, + 0x3c1a8000, 0x2403ff7f, 0x375b4000, 0x00431024, 0x3442380c, 0xac825000, + 0x8f430008, 0x3c100800, 0x37428000, 0x34630001, 0xaf430008, 0xaf82001c, + 0x3c02601c, 0xaf800028, 0xaf400080, 0xaf400084, 0x8c450008, 0x3c036000, + 0x8c620808, 0x3c040800, 0x3c030080, 0xac830820, 0x3042fff0, 0x38420010, + 0x2c420001, 0xaf850004, 0xaf820008, 0x0e00062f, 0x00000000, 0x8f420000, + 0x30420001, 0x1040fffb, 0x00000000, 0x8f440108, 0x30822000, 0xaf840034, + 0x10400004, 0x8e02083c, 0x24420001, 0x0a00059d, 0xae02083c, 0x30820200, + 0x10400027, 0x00000000, 0x97420104, 0x1040001c, 0x30824000, 0x14400005, + 0x00000000, 0x0e00022d, 0x00000000, 0x0a000592, 0x00000000, 0x8f620008, + 0x8f630000, 0x24020030, 0x00031e02, 0x306300f0, 0x10620007, 0x28620031, + 0x14400031, 0x24020040, 0x10620007, 0x00000000, 0x0a000592, 0x00000000, + 0x0e0002dd, 0x00000000, 0x0a000592, 0x00000000, 0x0e0003b8, 0x00000000, + 0x0a000592, 0x00000000, 0x30820040, 0x1440002d, 0x00000000, 0x0000000d, + 0x00000000, 0x240004a6, 0x0a00059d, 0x00000000, 0x8f430100, 0x24020d00, + 0x1462000f, 0x30820006, 0x97420104, 0x10400005, 0x30820040, 0x0e0004e9, + 0x00000000, 0x0a000592, 0x00000000, 0x1440001b, 0x00000000, 0x0000000d, + 0x00000000, 0x240004b8, 0x0a00059d, 0x00000000, 0x1040000e, 0x30821000, + 0x10400005, 0x00000000, 0x0e00065d, 0x00000000, 0x0a000592, 0x00000000, + 0x0e00046b, 0x00000000, 0x8f820040, 0x24420001, 0xaf820040, 0x0a00059d, + 0x00000000, 0x30820040, 0x14400004, 0x00000000, 0x0000000d, 0x00000000, + 0x240004cf, 0x8f420138, 0x3c034000, 0x00431025, 0xaf420138, 0x0a00053f, + 0x00000000, 0x3c046008, 0x8c835000, 0x3c1a8000, 0x2402ff7f, 0x375b4000, + 0x00621824, 0x3463380c, 0xac835000, 0x8f420008, 0x3c056000, 0x3c03601c, + 0x34420001, 0xaf420008, 0x37428000, 0xaf800028, 0xaf82001c, 0xaf400080, + 0xaf400084, 0x8c660008, 0x8ca20808, 0x3c040800, 0x3c030080, 0xac830820, + 0x3042fff0, 0x38420010, 0x2c420001, 0xaf860004, 0xaf820008, 0x03e00008, + 0x00000000, 0x3084ffff, 0x30820007, 0x10400002, 0x24820007, 0x3044fff8, + 0x8f820028, 0x00441821, 0x30631fff, 0x24644000, 0x0344d821, 0xaf820018, + 0xaf830028, 0x03e00008, 0xaf430084, 0x3084ffff, 0x30820007, 0x10400002, + 0x24820007, 0x3044fff8, 0x8f820044, 0x8f830004, 0x00442021, 0xaf82002c, + 0x0083102b, 0xaf840044, 0x14400002, 0x00831023, 0xaf820044, 0x8f820044, + 0x34038000, 0x00431821, 0x03432021, 0xaf84001c, 0x03e00008, 0xaf420080, + 0x8f830034, 0x24020002, 0x30630006, 0x1062000d, 0x2c620003, 0x50400005, + 0x24020004, 0x10600012, 0x3c020001, 0x0a000601, 0x00000000, 0x10620007, + 0x24020006, 0x1462000f, 0x3c020111, 0x0a0005f9, 0x00821025, 0x0a0005f8, + 0x3c020101, 0x3c020011, 0x00821025, 0x24030001, 0xaf421000, 0xaf830030, + 0x0a000601, 0x00000000, 0x00821025, 0xaf421000, 0xaf800030, 0x00000000, + 0x00000000, 0x00000000, 0x03e00008, 0x00000000, 0x8f820030, 0x10400005, + 0x3c038000, 0x8f421000, 0x00431024, 0x1040fffd, 0x00000000, 0x03e00008, + 0x00000000, 0x8f820034, 0x27bdffe8, 0x30424000, 0x14400005, 0xafbf0010, + 0x0e00022d, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x8f620008, 0x8f630000, + 0x24020030, 0x00031e02, 0x306300f0, 0x10620008, 0x28620031, 0x1440000d, + 0x8fbf0010, 0x24020040, 0x10620007, 0x00000000, 0x0a00062d, 0x00000000, + 0x0e0002dd, 0x00000000, 0x0a00062d, 0x8fbf0010, 0x0e0003b8, 0x00000000, + 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x8f84003c, 0x1080000f, 0x3c026000, + 0x8c430c3c, 0x30630fff, 0xaf830014, 0x14600011, 0x3082000f, 0x10400005, + 0x308200f0, 0x10400003, 0x30820f00, 0x14400006, 0x00000000, 0x0000000d, + 0x00000000, 0x2400050e, 0x03e00008, 0x00000000, 0x0000000d, 0x00000000, + 0x24000513, 0x03e00008, 0x00000000, 0xaf83003c, 0x03e00008, 0x00000000, + 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, 0xac820000, + 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000659, 0x00a01021, + 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, 0x03e00008, + 0x00000000, 0x0000000d, 0x03e00008, 0x00000000, 0x3c040800, 0x8c82084c, + 0x54400007, 0xac80084c, 0x8f820034, 0x24030400, 0x30420c00, 0x1443005b, + 0x00000000, 0xac80084c, 0x0000000d, 0x00000000, 0x2400003c, 0x3c026000, + 0x8c444448, 0x3c030800, 0xac640850, 0x24000043, 0x97420104, 0x3045ffff, + 0x000530c2, 0x24a2007f, 0x000239c2, 0x2400004e, 0x3c046020, 0x24030020, + 0xac830000, 0x8c820000, 0x30420020, 0x10400005, 0x3c036020, 0x8c620000, + 0x30420020, 0x1440fffd, 0x00000000, 0x3c026020, 0x8c430010, 0x24040001, + 0x0087102b, 0x30ea007f, 0x24abfffe, 0x10400010, 0x00034240, 0x3c056020, + 0x24090020, 0xaca90000, 0x8ca20000, 0x30420020, 0x10400006, 0x24840001, + 0x3c036020, 0x8c620000, 0x30420020, 0x1440fffd, 0x00000000, 0x0087102b, + 0x1440fff4, 0x00000000, 0x8f85001c, 0x3c026020, 0x8c430010, 0x3c046020, + 0x34848000, 0x006a1825, 0x01034025, 0x2400006b, 0x10c0000b, 0x00000000, + 0x8ca30000, 0x24a50004, 0x8ca20000, 0x24a50004, 0x24c6ffff, 0xac820000, + 0x24840004, 0xac830000, 0x14c0fff7, 0x24840004, 0x24000077, 0x3c020007, + 0x34427700, 0x3c036000, 0xac6223c8, 0xac6b23cc, 0xac6823e4, 0x24000086, + 0x3c046000, 0x3c038000, 0x8c8223f8, 0x00431024, 0x1440fffd, 0x3c021000, + 0x3c056000, 0x24030019, 0xaca223f8, 0xa743014a, 0x8ca44448, 0x3c020800, + 0xac440854, 0x03e00008, 0x00000000, 0x00000000 }; + +static u32 bnx2_TPAT_b06FwData[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_TPAT_b06FwRodata[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_TPAT_b06FwBss[(0x80/4) + 1] = { 0x00000000 }; +static u32 bnx2_TPAT_b06FwSbss[(0x48/4) + 1] = { 0x00000000 }; + +static int bnx2_TXP_b06FwReleaseMajor = 0x0; +static int bnx2_TXP_b06FwReleaseMinor = 0x0; +static int bnx2_TXP_b06FwReleaseFix = 0x0; +static u32 bnx2_TXP_b06FwStartAddr = 0x08002090; +static u32 bnx2_TXP_b06FwTextAddr = 0x08000000; +static int bnx2_TXP_b06FwTextLen = 0x3ffc; +static u32 bnx2_TXP_b06FwDataAddr = 0x08004020; +static int bnx2_TXP_b06FwDataLen = 0x0; +static u32 bnx2_TXP_b06FwRodataAddr = 0x00000000; +static int bnx2_TXP_b06FwRodataLen = 0x0; +static u32 bnx2_TXP_b06FwBssAddr = 0x08004060; +static int bnx2_TXP_b06FwBssLen = 0x194; +static u32 bnx2_TXP_b06FwSbssAddr = 0x08004020; +static int bnx2_TXP_b06FwSbssLen = 0x34; +static u32 bnx2_TXP_b06FwText[(0x3ffc/4) + 1] = { + 0x0a000824, 0x00000000, 0x00000000, 0x0000000d, 0x74787020, 0x302e362e, + 0x39000000, 0x00060900, 0x0000000a, 0x000003e8, 0x0000ea60, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d, + 0x0000000d, 0x3c020800, 0x24424020, 0x3c030800, 0x246341f4, 0xac400000, + 0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021, + 0x3c100800, 0x26102090, 0x3c1c0800, 0x279c4020, 0x0e000a0e, 0x00000000, + 0x0000000d, 0x8f840014, 0x27bdffe8, 0xafb00010, 0x8f460104, 0x8f830008, + 0x8c8500ac, 0xaf430080, 0x948200a8, 0xa7420e10, 0x948300aa, 0xa7430e12, + 0x8c8200ac, 0xaf420e18, 0x97430e10, 0xa7430e14, 0x97420e12, 0xa7420e16, + 0x8f430e18, 0x00005021, 0x00c53023, 0x10c001a3, 0xaf430e1c, 0x240f0800, + 0x3c0e1000, 0x2419fff8, 0x24100010, 0x3c188100, 0x93620008, 0x10400009, + 0x00000000, 0x97620010, 0x00c2102b, 0x14400005, 0x00000000, 0x97620010, + 0x3042ffff, 0x0a000862, 0xaf420e00, 0xaf460e00, 0x8f420000, 0x30420008, + 0x1040fffd, 0x00000000, 0x97420e08, 0x8f450e04, 0x3044ffff, 0x30820001, + 0x14400005, 0x00000000, 0x14a00005, 0x3083a040, 0x0a0009e6, 0x00000000, + 0x0000000d, 0x3083a040, 0x24020040, 0x14620049, 0x3082a000, 0x8f87000c, + 0x30880036, 0x30890008, 0xaf4f0178, 0x00e01821, 0x9742008a, 0x00431023, + 0x2442ffff, 0x30421fff, 0x2c420008, 0x1440fffa, 0x00000000, 0x8f830018, + 0x00a05021, 0x00c53023, 0x24e24000, 0x03422821, 0x306b00ff, 0x24630001, + 0xaf830018, 0x93840012, 0x000b1400, 0x3c030100, 0x00431025, 0xaca20000, + 0x8f820018, 0x30840007, 0x00042240, 0x34870001, 0x00e83825, 0x1120000f, + 0xaca20004, 0x97430e0a, 0x8f84000c, 0x00ee3825, 0x2402000e, 0x00781825, + 0xaf430160, 0x25430006, 0x24840008, 0x30841fff, 0xa742015a, 0xa7430158, + 0xaf84000c, 0x0a0008a9, 0x00000000, 0x8f83000c, 0x25420002, 0xa7420158, + 0x24630008, 0x30631fff, 0xaf83000c, 0x54c0000c, 0x8f420e14, 0x97420e10, + 0x97430e12, 0x8f840014, 0x00021400, 0x00621825, 0xac8300a8, 0x8f850014, + 0x8f420e18, 0x34e70040, 0xaca200ac, 0x8f420e14, 0x8f430e1c, 0xaf420144, + 0xaf430148, 0xa34b0152, 0xaf470154, 0x0a0009f1, 0xaf4e0178, 0x10400128, + 0x00000000, 0x97620010, 0x00a2102b, 0x10400003, 0x30820040, 0x10400122, + 0x00000000, 0xafa60008, 0xa7840010, 0xaf850004, 0x93620008, 0x1440005e, + 0x27ac0008, 0xaf60000c, 0x97820010, 0x30424000, 0x10400002, 0x2403000e, + 0x24030016, 0xa363000a, 0x24034007, 0xaf630014, 0x93820012, 0x8f630014, + 0x30420007, 0x00021240, 0x00621825, 0xaf630014, 0x97820010, 0x8f630014, + 0x30420010, 0x00621825, 0xaf630014, 0x97820010, 0x30420008, 0x5040000e, + 0x00002821, 0x8f620014, 0x004e1025, 0xaf620014, 0x97430e0a, 0x2402000e, + 0x00781825, 0xaf630004, 0xa3620002, 0x9363000a, 0x3405fffc, 0x24630004, + 0x0a0008f2, 0xa363000a, 0xaf600004, 0xa3600002, 0x97820010, 0x9363000a, + 0x30421f00, 0x00021182, 0x24420028, 0x00621821, 0xa3630009, 0x97420e0c, + 0xa7620010, 0x93630009, 0x24020008, 0x24630002, 0x30630007, 0x00431023, + 0x30420007, 0xa362000b, 0x93640009, 0x97620010, 0x8f890004, 0x97830010, + 0x00441021, 0x00a21021, 0x30630040, 0x10600006, 0x3045ffff, 0x15250005, + 0x0125102b, 0x3c068000, 0x0a000925, 0x00005821, 0x0125102b, 0x144000c8, + 0x00005021, 0x97420e14, 0xa7420e10, 0x97430e16, 0xa7430e12, 0x8f420e1c, + 0xaf420e18, 0xaf450e00, 0x8f420000, 0x30420008, 0x1040fffd, 0x00000000, + 0x97420e08, 0x00a04821, 0xa7820010, 0x8f430e04, 0x00003021, 0x240b0001, + 0xaf830004, 0x97620010, 0x0a000936, 0x304dffff, 0x8f890004, 0x97820010, + 0x30420040, 0x10400004, 0x01206821, 0x3c068000, 0x0a000936, 0x00005821, + 0x97630010, 0x8f820004, 0x144300a7, 0x00005021, 0x00003021, 0x240b0001, + 0x8d820000, 0x00491023, 0x1440000d, 0xad820000, 0x8f620014, 0x34420040, + 0xaf620014, 0x97430e10, 0x97420e12, 0x8f840014, 0x00031c00, 0x00431025, + 0xac8200a8, 0x8f830014, 0x8f420e18, 0xac6200ac, 0x93620008, 0x1440003f, + 0x00000000, 0x25260002, 0x8f84000c, 0x9743008a, 0x3063ffff, 0xafa30000, + 0x8fa20000, 0x00441023, 0x2442ffff, 0x30421fff, 0x2c420010, 0x1440fff7, + 0x00000000, 0x8f82000c, 0x8f830018, 0x00021082, 0x00021080, 0x24424000, + 0x03422821, 0x00605021, 0x24630001, 0x314200ff, 0x00021400, 0xaf830018, + 0x3c033200, 0x00431025, 0xaca20000, 0x93630009, 0x9362000a, 0x00031c00, + 0x00431025, 0xaca20004, 0x8f830018, 0xaca30008, 0x97820010, 0x30420008, + 0x10400002, 0x00c04021, 0x25280006, 0x97430e14, 0x93640002, 0x8f450e1c, + 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, 0x97420e16, + 0xa7420146, 0xaf450148, 0xa34a0152, 0x8f82000c, 0x308400ff, 0xa744015a, + 0xaf460160, 0xa7480158, 0xaf470154, 0xaf4e0178, 0x00501021, 0x30421fff, + 0xaf82000c, 0x0a0009c5, 0x8d820000, 0x93620009, 0x9363000b, 0x8f85000c, + 0x2463000a, 0x00435021, 0x25440007, 0x00992024, 0x9743008a, 0x3063ffff, + 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, + 0x1440fff7, 0x00000000, 0x8f82000c, 0x8f840018, 0x00021082, 0x00021080, + 0x24424000, 0x03422821, 0x00804021, 0x24840001, 0xaf840018, 0x93630009, + 0x310200ff, 0x00022400, 0x3c024100, 0x24630002, 0x00621825, 0x00832025, + 0xaca40000, 0x8f62000c, 0x00461025, 0xaca20004, 0x97430e14, 0x93640002, + 0x8f450e1c, 0x8f660004, 0x8f670014, 0xaf4f0178, 0x3063ffff, 0xa7430144, + 0x97420e16, 0x308400ff, 0xa7420146, 0xaf450148, 0xa3480152, 0x8f83000c, + 0x25420007, 0x00591024, 0xa744015a, 0xaf460160, 0xa7490158, 0xaf470154, + 0xaf4e0178, 0x00621821, 0x30631fff, 0xaf83000c, 0x8d820000, 0x14400005, + 0x00000000, 0x8f620014, 0x2403ffbf, 0x00431024, 0xaf620014, 0x8f62000c, + 0x004d1021, 0xaf62000c, 0x93630008, 0x14600008, 0x00000000, 0x11600006, + 0x00000000, 0x8f630014, 0x3c02efff, 0x3442fffe, 0x00621824, 0xaf630014, + 0xa36b0008, 0x01205021, 0x15400016, 0x8fa60008, 0x97420e14, 0x97430e16, + 0x8f850014, 0x00021400, 0x00621825, 0xaca300a8, 0x8f840014, 0x8f420e1c, + 0x0a0009f3, 0xac8200ac, 0x97420e14, 0x97430e16, 0x8f840014, 0x00021400, + 0x00621825, 0xac8300a8, 0x8f850014, 0x8f420e1c, 0x00005021, 0x0a0009f3, + 0xaca200ac, 0x14c0fe64, 0x00000000, 0x55400018, 0x8fb00010, 0x3c038000, + 0x8f420178, 0x00431024, 0x1440fffd, 0x00000000, 0x97430e14, 0x8f440e1c, + 0x24020800, 0xaf420178, 0x3063ffff, 0xa7430144, 0x97420e16, 0x3c031000, + 0xa7420146, 0x24020240, 0xaf440148, 0xa3400152, 0xa740015a, 0xaf400160, + 0xa7400158, 0xaf420154, 0xaf430178, 0x8fb00010, 0x03e00008, 0x27bd0018, + 0x27bdffd8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821, + 0xafbf0020, 0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0xaf830014, + 0xaf440e00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, 0x8c835000, 0x24130d00, + 0x3c120800, 0x3c114000, 0x2402ff7f, 0x00621824, 0x3463380c, 0x24020009, + 0xac835000, 0xaf420008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, + 0x0e000a96, 0x00000000, 0x3c020800, 0x24504080, 0x8f420000, 0x30420001, + 0x1040fffd, 0x00000000, 0x8f440100, 0xaf840008, 0xaf440020, 0x93430108, + 0xa3830012, 0x93820012, 0x30420001, 0x10400008, 0x00000000, 0x93820012, + 0x30420006, 0x00021100, 0x0e00083b, 0x0050d821, 0x0a000a52, 0x00000000, + 0x14930005, 0x00000000, 0x0e00083b, 0x265b4100, 0x0a000a52, 0x00000000, + 0x0e000ba3, 0x00000000, 0xaf510138, 0x0a000a36, 0x00000000, 0x27bdfff8, + 0x3084ffff, 0x24820007, 0x3044fff8, 0x8f85000c, 0x9743008a, 0x3063ffff, + 0xafa30000, 0x8fa20000, 0x00451023, 0x2442ffff, 0x30421fff, 0x0044102b, + 0x1440fff7, 0x00000000, 0x8f82000c, 0x00021082, 0x00021080, 0x24424000, + 0x03421021, 0x03e00008, 0x27bd0008, 0x3084ffff, 0x8f82000c, 0x24840007, + 0x3084fff8, 0x00441021, 0x30421fff, 0xaf82000c, 0x03e00008, 0x00000000, + 0x27bdffe8, 0x3c1a8000, 0x3c0420ff, 0x3484fffd, 0x3c020008, 0x03421821, + 0xafbf0010, 0xaf830014, 0xaf440e00, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x3c0200ff, 0x3442fffd, 0x3c046004, 0xaf420e00, + 0x8c825000, 0x2403ff7f, 0x00431024, 0x3442380c, 0x24030009, 0xac825000, + 0xaf430008, 0xaf800018, 0xaf80000c, 0x0e000fa1, 0x00000000, 0x0e000a96, + 0x00000000, 0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe8, 0x3c02000a, + 0x03421821, 0x3c040800, 0x24844120, 0x24050018, 0xafbf0010, 0xaf830024, + 0x0e000fad, 0x00003021, 0x3c050800, 0x3c020800, 0x24423d60, 0xaca24180, + 0x24a54180, 0x3c020800, 0x24423e18, 0x3c030800, 0x24633e2c, 0x3c040800, + 0xaca20004, 0x3c020800, 0x24423d68, 0xaca30008, 0xac824190, 0x24844190, + 0x3c020800, 0x24423da4, 0x3c070800, 0x24e73de4, 0x3c060800, 0x24c63e40, + 0x3c050800, 0x24a52b28, 0x3c030800, 0xac820004, 0x3c020800, 0x24423e48, + 0xac870008, 0xac86000c, 0xac850010, 0xac6241b0, 0x246341b0, 0x8fbf0010, + 0x3c020800, 0x24423e60, 0xac620004, 0xac670008, 0xac66000c, 0xac650010, + 0x03e00008, 0x27bd0018, 0x27bdffc8, 0x3c020800, 0x24424120, 0xafbf0030, + 0xafb3002c, 0xafb20028, 0xafb10024, 0xafb00020, 0x90470021, 0x8c510008, + 0x8c45001c, 0x8f900020, 0x3c060800, 0x3c038000, 0x8f420178, 0x00431024, + 0x1440fffd, 0x8cc2414c, 0x24c3414c, 0x2473ffd4, 0xaf420144, 0x8e620030, + 0x30b22000, 0xaf420148, 0x3c021000, 0xaf50014c, 0xa3470152, 0xa7510158, + 0xaf450154, 0xaf420178, 0x12400004, 0x3c030800, 0x8c620030, 0x24420001, + 0xac620030, 0x93420109, 0x9344010a, 0x00111c00, 0xafa30018, 0x00071a00, + 0xafa50014, 0x8cc5414c, 0x00021600, 0x00042400, 0x00441025, 0x00431025, + 0xafa20010, 0x8f440100, 0x8e660030, 0x0e000fe1, 0x02003821, 0x1640000e, + 0x8fbf0030, 0x8f820000, 0x8e630030, 0x8c44017c, 0x02031823, 0x00711823, + 0x00641823, 0x2c630002, 0x14600006, 0x8fb3002c, 0x0000000d, 0x00000000, + 0x240000ca, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024, 0x8fb00020, + 0x03e00008, 0x27bd0038, 0x974309da, 0x00804021, 0xad030000, 0x8f4209dc, + 0xad020004, 0x8f4309e0, 0xad030008, 0x934409d9, 0x24020001, 0x30840003, + 0x1082001f, 0x30a900ff, 0x28820002, 0x10400005, 0x24020002, 0x10800009, + 0x3c0a0800, 0x0a000b64, 0x93420934, 0x1082000b, 0x24020003, 0x10820026, + 0x3c0a0800, 0x0a000b64, 0x93420934, 0x974209e4, 0x00021400, 0x34420800, + 0xad02000c, 0x0a000b63, 0x25080010, 0x974209e4, 0x00021400, 0x34428100, + 0xad02000c, 0x974309e8, 0x3c0a0800, 0x00031c00, 0x34630800, 0xad030010, + 0x0a000b63, 0x25080014, 0x974409e4, 0x3c050800, 0x24a24120, 0x94430018, + 0x94460010, 0x9447000c, 0x00a05021, 0x24020800, 0xad000010, 0xad020014, + 0x00042400, 0x00661821, 0x00671823, 0x2463fff2, 0x00832025, 0xad04000c, + 0x0a000b63, 0x25080018, 0x974209e4, 0x3c050800, 0x00021400, 0x34428100, + 0xad02000c, 0x974409e8, 0x24a24120, 0x94430018, 0x94460010, 0x9447000c, + 0x00a05021, 0x24020800, 0xad000014, 0xad020018, 0x00042400, 0x00661821, + 0x00671823, 0x2463ffee, 0x00832025, 0xad040010, 0x2508001c, 0x93420934, + 0x93450921, 0x3c074000, 0x25444120, 0x94830014, 0x94860010, 0x00021082, + 0x00021600, 0x00052c00, 0x00a72825, 0x00451025, 0x00661821, 0x00431025, + 0xad020000, 0x97830028, 0x974209ea, 0x00621821, 0x00031c00, 0xad030004, + 0x97820028, 0x24420001, 0x30427fff, 0xa7820028, 0x93430920, 0x3c020006, + 0x00031e00, 0x00621825, 0xad030008, 0x8f42092c, 0xad02000c, 0x8f430930, + 0xad030010, 0x8f440938, 0x25080014, 0xad040000, 0x8f820020, 0x11200004, + 0xad020004, 0x8f420940, 0x0a000b8d, 0x2442ffff, 0x8f420940, 0xad020008, + 0x8f440948, 0x8f420940, 0x93430936, 0x00822823, 0x00652806, 0x3402ffff, + 0x0045102b, 0x54400001, 0x3405ffff, 0x93420937, 0x25444120, 0x90830020, + 0xad000010, 0x00021700, 0x34630010, 0x00031c00, 0x00431025, 0x00451025, + 0xad02000c, 0x03e00008, 0x25020014, 0x27bdffb0, 0x3c020008, 0x03421821, + 0xafbf004c, 0xafbe0048, 0xafb70044, 0xafb60040, 0xafb5003c, 0xafb40038, + 0xafb30034, 0xafb20030, 0xafb1002c, 0xafb00028, 0xaf830000, 0x24020040, + 0xaf420814, 0xaf400810, 0x8f420944, 0x8f430950, 0x8f440954, 0x8f45095c, + 0xaf820030, 0xaf830020, 0xaf84001c, 0xaf85002c, 0x93430900, 0x24020020, + 0x10620005, 0x24020030, 0x10620022, 0x3c030800, 0x0a000bf1, 0x8c62002c, + 0x24020088, 0xaf420818, 0x3c020800, 0x24424180, 0xafa20020, 0x93430109, + 0x3c020800, 0x10600009, 0x24574190, 0x3c026000, 0x24030100, 0xac43081c, + 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x2400031d, 0x9342010a, + 0x30420080, 0x1440001c, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c, + 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000324, 0x0a000bf4, + 0x00000000, 0x93430109, 0x3063007f, 0x00031140, 0x000318c0, 0x00431021, + 0x24430088, 0xaf430818, 0x0000000d, 0x3c020800, 0x244241d0, 0x3c030800, + 0x247741e0, 0x0a000bf4, 0xafa20020, 0x24420001, 0x0a000f4c, 0xac62002c, + 0x8f840000, 0x8f850020, 0x24020800, 0xaf420178, 0x8f4209a4, 0x8c83017c, + 0x00a21023, 0x00431023, 0x2c420002, 0x14400004, 0x00000000, 0x0000000d, + 0x00000000, 0x24000349, 0x8f420104, 0x8f430988, 0x00431023, 0x58400005, + 0x8f4209a0, 0x0000000d, 0x00000000, 0x2400034d, 0x8f4209a0, 0x3c100800, + 0xae02414c, 0x8f4309a4, 0x2604414c, 0x2491ffd4, 0xae230030, 0x8f420104, + 0xae250024, 0x00431023, 0xac82ffd4, 0x8fa30020, 0x8c620000, 0x0040f809, + 0x0200b021, 0x00409021, 0x32440010, 0x32420002, 0x10400007, 0xafa40024, + 0x8e22001c, 0x32500040, 0x2403ffbf, 0x00431024, 0x0a000f13, 0xae22001c, + 0x32420020, 0x10400002, 0x3c020800, 0x245741b0, 0x32420001, 0x14400007, + 0x00000000, 0x8f820008, 0xaf420080, 0x8ec3414c, 0xaf430e10, 0x8e220030, + 0xaf420e18, 0x9343010b, 0x93420905, 0x30420008, 0x1040003c, 0x307400ff, + 0x8f820000, 0x8c430074, 0x0460000a, 0x00000000, 0x3c026000, 0x24030100, + 0xac43081c, 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x24000384, + 0x8f820000, 0x9044007b, 0x9343010a, 0x14830027, 0x32500040, 0x24072000, + 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c, + 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, 0xaf420148, + 0x24020047, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158, + 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001, + 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600, + 0x00031c00, 0x00431025, 0x34424700, 0xafa20010, 0x8f440100, 0x0e000fe1, + 0x3c070100, 0x3c030800, 0x24624120, 0x0a000d01, 0x8c43001c, 0x32820002, + 0x10400047, 0x3c039000, 0x34630001, 0x8f820008, 0x32500040, 0x3c048000, + 0x00431025, 0xaf420020, 0x8f420020, 0x00441024, 0x1440fffd, 0x00000000, + 0x8f830000, 0x90620005, 0x3c058000, 0x34420008, 0xa0620005, 0x8f860000, + 0x34a50001, 0x8f840008, 0x8cc20074, 0x3c038000, 0x00852025, 0x00431025, + 0xacc20074, 0xaf440020, 0x90c3007b, 0x9342010a, 0x14620028, 0x3c040800, + 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, + 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030100, + 0xaf420148, 0x24020046, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, + 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, + 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, + 0x00021600, 0x00031c00, 0x00431025, 0x34424600, 0xafa20010, 0x8f440100, + 0x0e000fe1, 0x3c070100, 0x3c040800, 0x24824120, 0x0a000d01, 0x8c43001c, + 0x93420108, 0x30420010, 0x50400050, 0x9343093f, 0x8f860000, 0x90c3007f, + 0x90c2007e, 0x90c40080, 0x306800ff, 0x00021600, 0x00081c00, 0x00431025, + 0x00042200, 0x90c3007a, 0x90c5000a, 0x00441025, 0x11050028, 0x00623825, + 0xa0c8000a, 0x24086000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, + 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, + 0x00001821, 0xaf420148, 0x24020052, 0xaf47014c, 0xa3420152, 0x3c021000, + 0xa7430158, 0xaf480154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, + 0x24630001, 0xad230030, 0x93420109, 0x9343010a, 0xafa80014, 0xafa00018, + 0x00021600, 0x00031c00, 0x00431025, 0x34425200, 0xafa20010, 0x0e000fe1, + 0x8f440100, 0x0a000cfb, 0x00000000, 0x3c026000, 0x24030100, 0xac43081c, + 0x3c030001, 0xac43081c, 0x0000000d, 0x00000000, 0x240003cd, 0x16800009, + 0x3c040800, 0x3c030800, 0x24624120, 0x8c43001c, 0x32500040, 0x2404ffbf, + 0x00641824, 0x0a000f13, 0xac43001c, 0x8c824120, 0x10400005, 0x3c030800, + 0x8c620034, 0xac804120, 0x24420001, 0xac620034, 0x9343093f, 0x24020012, + 0x1462000f, 0x329e0038, 0x17c0000c, 0x3c030800, 0x8f830000, 0x8c62004c, + 0xac62005c, 0x3c020800, 0x24444120, 0x8c82001c, 0x32500040, 0x2403ffbf, + 0x00431024, 0x0a000f13, 0xac82001c, 0xac604120, 0x97420908, 0x000211c0, + 0xaf420024, 0x97420908, 0x3c030080, 0x34630003, 0x000211c0, 0xaf42080c, + 0xaf43081c, 0x974209ec, 0x8f4309a4, 0xa7820028, 0x3c020800, 0x24444120, + 0xac830028, 0x93420937, 0x93430934, 0x00021080, 0x00621821, 0xa4830014, + 0x934209d8, 0x00621821, 0xa4830016, 0x934209d8, 0x93430934, 0x00809821, + 0x00431021, 0x24420010, 0xa4820012, 0x0000a821, 0x24020006, 0x13c00003, + 0xae62001c, 0x0a000d82, 0x24120008, 0x8f420958, 0x8f830020, 0x8f84002c, + 0x00431023, 0x00832023, 0x04800003, 0xae620004, 0x04410003, 0x0082102b, + 0x0a000d4e, 0xae600004, 0x54400001, 0xae640004, 0x8ee20000, 0x0040f809, + 0x00000000, 0x00409021, 0x32420001, 0x5440001e, 0x8ee20004, 0x8e630008, + 0x1060002b, 0x3c02c000, 0x00621025, 0xaf420e00, 0x8f420000, 0x30420008, + 0x1040fffd, 0x00000000, 0x97420e08, 0xa7820010, 0x8f430e04, 0x8e620008, + 0xaf830004, 0x8f840004, 0x0044102b, 0x1040000b, 0x24150001, 0x24020100, + 0x3c016000, 0xac22081c, 0x3c020001, 0x3c016000, 0xac22081c, 0x0000000d, + 0x00000000, 0x24000449, 0x24150001, 0x8ee20004, 0x0040f809, 0x00000000, + 0x02429025, 0x32420002, 0x5040001d, 0x8f470940, 0x12a00006, 0x8ec2414c, + 0x8f830000, 0xac6200a8, 0x8f840000, 0x8e620030, 0xac8200ac, 0x32420004, + 0x50400013, 0x8f470940, 0x3c020800, 0x3283007d, 0x106000fe, 0x245741b0, + 0x32820001, 0x50400006, 0x36520002, 0x8f830030, 0x8f420940, 0x106200f7, + 0x00000000, 0x36520002, 0x24020008, 0xa660000c, 0xa662000e, 0xae600008, + 0xa2600020, 0x8f470940, 0x3c030800, 0x24684120, 0x8d020028, 0x8d050008, + 0x9504000c, 0x9506000a, 0x95030022, 0x00451021, 0x00862021, 0x00641821, + 0xaf870030, 0xad020028, 0x32820030, 0x10400006, 0xa5030010, 0x91020020, + 0x32910040, 0x34420004, 0x0a000dd4, 0xa1020020, 0x93420923, 0x30420040, + 0x10400029, 0x32910040, 0x8f830000, 0x8f840020, 0x8c620084, 0x00441023, + 0x0442000a, 0x3c039000, 0x95020010, 0x8c630084, 0x00821021, 0x00621823, + 0x1c600004, 0x3c039000, 0x91020020, 0x34420001, 0xa1020020, 0x34630001, + 0x8f820008, 0x32910040, 0x3c048000, 0x00431025, 0xaf420020, 0x8f420020, + 0x00441024, 0x1440fffd, 0x00000000, 0x8f840000, 0x9083003f, 0x2402000a, + 0x10620005, 0x2402000c, 0x9083003f, 0x24020008, 0x14620002, 0x24020014, + 0xa082003f, 0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, + 0x3c040800, 0x24904120, 0x9602000c, 0x96030016, 0x9604000e, 0x00431021, + 0x00442021, 0x24840002, 0x3084ffff, 0x0e000a55, 0xa6020018, 0x8f850018, + 0x00a01821, 0xa2030021, 0x8ee60008, 0x00402021, 0x24a50001, 0xaf850018, + 0x00c0f809, 0x00000000, 0x00402021, 0x0e000b12, 0x02202821, 0x8ee3000c, + 0x0060f809, 0x00402021, 0x96040018, 0x9602000e, 0x00822021, 0x24840002, + 0x0e000a6b, 0x3084ffff, 0x3c030800, 0x8c624120, 0x8e030008, 0x3c040800, + 0x00431023, 0x14400012, 0xac824120, 0x54600006, 0x8e02001c, 0x3243004a, + 0x24020002, 0x14620005, 0x00000000, 0x8e02001c, 0x34420040, 0x0a000e0b, + 0xae02001c, 0x52a00006, 0x36520002, 0x8e02002c, 0xaf420e10, 0x8e030030, + 0xaf430e18, 0x36520002, 0x52a00008, 0x96670010, 0x8f830000, 0x8f420e10, + 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670010, 0x92680020, + 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821, 0x00621023, + 0xaf830020, 0x58400005, 0x8f42095c, 0x8f820000, 0xaf83001c, 0xac430054, + 0x8f42095c, 0x31030008, 0xaf82002c, 0x1060001a, 0x00000000, 0x8f840000, + 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, 0x24020007, + 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, 0x8f850000, + 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, 0x30630007, + 0xac440000, 0x0a000e40, 0xa0a30120, 0x90820122, 0x34420001, 0xa0820122, + 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, 0x8c43000c, + 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, 0x34420001, + 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd, + 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, 0x00000000, + 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, 0x90e40081, + 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001, + 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, 0x00c02021, + 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, 0x8f830008, + 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f830020, 0x3c020800, + 0x24504120, 0xae030024, 0x8ee20010, 0x0040f809, 0x00000000, 0x12a00005, + 0x00000000, 0x8f420e10, 0xae02002c, 0x8f430e18, 0xae030030, 0x1220feba, + 0x0000a821, 0x8f870024, 0x97860028, 0x8f830000, 0x8f820030, 0x8f840020, + 0x8f85001c, 0x32500040, 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, + 0xac650054, 0x1040007a, 0x32820020, 0x10400027, 0x32910010, 0x24072000, + 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c, + 0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030400, 0xaf420148, + 0x24020041, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158, + 0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001, + 0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600, + 0x00031c00, 0x00431025, 0x34424100, 0xafa20010, 0x8f440100, 0x0e000fe1, + 0x3c070400, 0x12200028, 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178, + 0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, + 0x8c820030, 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0x00001821, + 0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, + 0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a, + 0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424e00, + 0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070300, 0x0a000f0b, 0x8fa30024, + 0x32820008, 0x10400026, 0x3c090800, 0x24072000, 0x3c038000, 0x8f420178, + 0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144, + 0x8c820030, 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0x00001821, + 0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c, + 0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a, + 0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424b00, + 0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070200, 0x8fa30024, 0x14600004, + 0x8fa40020, 0x32420010, 0x10400004, 0x00000000, 0x8c820004, 0x0040f809, + 0x00000000, 0x12000006, 0x8fa30020, 0x8c620008, 0x0040f809, 0x00000000, + 0x0a000f4d, 0x8fbf004c, 0x3c030800, 0x8c62413c, 0x30420040, 0x1440002f, + 0x8fbf004c, 0x24040040, 0x8f910020, 0x3c038000, 0x8f420178, 0x00431024, + 0x1440fffd, 0x8ec2414c, 0x26d0414c, 0x2610ffd4, 0xaf420144, 0x8e020030, + 0x00001821, 0xaf420148, 0x24020049, 0xaf51014c, 0xa3420152, 0x3c021000, + 0xa7430158, 0xaf440154, 0xaf420178, 0x8ec5414c, 0x8e060030, 0x93420109, + 0x9343010a, 0xafa40014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, + 0x34424900, 0xafa20010, 0x8f440100, 0x0e000fe1, 0x02203821, 0x8f830000, + 0x8e020030, 0x8c64017c, 0x02221023, 0x00441023, 0x2c420002, 0x14400005, + 0x8fbf004c, 0x0000000d, 0x00000000, 0x240000ca, 0x8fbf004c, 0x8fbe0048, + 0x8fb70044, 0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, 0x8fb20030, + 0x8fb1002c, 0x8fb00028, 0x03e00008, 0x27bd0050, 0x03e00008, 0x00001021, + 0x3c030800, 0x24654120, 0x8ca40004, 0x8c634120, 0x0064102b, 0x54400001, + 0x00602021, 0x9743093c, 0x0083102b, 0x54400001, 0x00801821, 0x00001021, + 0xaca30008, 0x03e00008, 0xa4a00022, 0x8f850004, 0x97840010, 0x3c030800, + 0x24634120, 0x24020008, 0xa462000e, 0x8f820004, 0xa460000c, 0x000420c2, + 0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008, + 0xa0640020, 0x3c020800, 0x24424120, 0x90450021, 0x94430018, 0x3c021100, + 0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008, + 0x03e00008, 0xac850000, 0x0000000d, 0x00000000, 0x2400016f, 0x03e00008, + 0x00000000, 0x0000000d, 0x00000000, 0x2400017b, 0x03e00008, 0x00000000, + 0x03e00008, 0x00000000, 0x3c020800, 0x24424120, 0xac400008, 0xa4400022, + 0x03e00008, 0x24020001, 0x3c020800, 0x24424120, 0x24030008, 0xac400008, + 0xa440000c, 0xa443000e, 0xa0400020, 0x03e00008, 0x24020004, 0x03e00008, + 0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004, + 0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000fb2, + 0x00a01021, 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff, + 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, 0x3c050800, 0x24a51090, + 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, 0x00a61021, 0xac440004, + 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, 0x00431025, 0xac820008, + 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, 0xac440010, 0x8f430e18, + 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, 0x25290001, 0xac470018, + 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, 0x24630001, 0xace3006c, + 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, 0x00042600, 0x00681824, + 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, 0x8fad0014, 0x8fae0018, + 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080078, 0x000a4940, 0x01281021, + 0x01091821, 0xac440000, 0x00601021, 0xac650004, 0xac460008, 0xac67000c, + 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, 0x8c654448, 0x3c040800, + 0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001, + 0xac820064, 0x03e00008, 0xad05001c, 0x00000000 }; + +static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 }; +static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 }; +static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 }; + -- cgit v1.2.2 From aa8f0dc6c3dbf1cf3ff58f3e945c981be134814d Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 26 May 2005 21:54:27 -0400 Subject: libata: Fix use-after-iounmap Jens Axboe pointed out that the iounmap() call in libata was occurring too early, and some drivers (ahci, probably others) were using ioremap'd memory after it had been unmapped. The patch should address that problem by way of improving the libata driver API: * move ->host_stop() call after all ->port_stop() calls have occurred. * create default helper function ata_host_stop(), and move iounmap() call there. * add ->host_stop_prewalk() hook, use it in sata_qstor.c (hi Mark). sata_qstor appears to require the host-stop-before-port-stop ordering that existed prior to applying the attached patch. --- drivers/scsi/ahci.c | 2 ++ drivers/scsi/ata_piix.c | 2 ++ drivers/scsi/libata-core.c | 15 +++++++++++---- drivers/scsi/sata_nv.c | 2 ++ drivers/scsi/sata_promise.c | 1 + drivers/scsi/sata_qstor.c | 2 ++ drivers/scsi/sata_sil.c | 1 + drivers/scsi/sata_sis.c | 1 + drivers/scsi/sata_svw.c | 1 + drivers/scsi/sata_sx4.c | 2 ++ drivers/scsi/sata_uli.c | 1 + drivers/scsi/sata_via.c | 1 + drivers/scsi/sata_vsc.c | 1 + 13 files changed, 28 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index da5bd33d982d..8b468a628700 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -289,6 +289,8 @@ static void ahci_host_stop(struct ata_host_set *host_set) { struct ahci_host_priv *hpriv = host_set->private_data; kfree(hpriv); + + ata_host_stop(host_set); } static int ahci_port_start(struct ata_port *ap) diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 3867f91ef8c7..54c52349adc5 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -153,6 +153,7 @@ static struct ata_port_operations piix_pata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_operations piix_sata_ops = { @@ -180,6 +181,7 @@ static struct ata_port_operations piix_sata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info piix_port_info[] = { diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index ee9b96da841e..2b41cd3a8ec6 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -3321,6 +3321,13 @@ void ata_port_stop (struct ata_port *ap) dma_free_coherent(dev, ATA_PRD_TBL_SZ, ap->prd, ap->prd_dma); } +void ata_host_stop (struct ata_host_set *host_set) +{ + if (host_set->mmio_base) + iounmap(host_set->mmio_base); +} + + /** * ata_host_remove - Unregister SCSI host structure with upper layers * @ap: Port to unregister @@ -3877,10 +3884,6 @@ void ata_pci_remove_one (struct pci_dev *pdev) } free_irq(host_set->irq, host_set); - if (host_set->ops->host_stop) - host_set->ops->host_stop(host_set); - if (host_set->mmio_base) - iounmap(host_set->mmio_base); for (i = 0; i < host_set->n_ports; i++) { ap = host_set->ports[i]; @@ -3899,6 +3902,9 @@ void ata_pci_remove_one (struct pci_dev *pdev) scsi_host_put(ap->host); } + if (host_set->ops->host_stop) + host_set->ops->host_stop(host_set); + kfree(host_set); pci_release_regions(pdev); @@ -3996,6 +4002,7 @@ EXPORT_SYMBOL_GPL(ata_chk_err); EXPORT_SYMBOL_GPL(ata_exec_command); EXPORT_SYMBOL_GPL(ata_port_start); EXPORT_SYMBOL_GPL(ata_port_stop); +EXPORT_SYMBOL_GPL(ata_host_stop); EXPORT_SYMBOL_GPL(ata_interrupt); EXPORT_SYMBOL_GPL(ata_qc_prep); EXPORT_SYMBOL_GPL(ata_bmdma_setup); diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index 69009f853a49..b0403ccd8a25 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c @@ -329,6 +329,8 @@ static void nv_host_stop (struct ata_host_set *host_set) host->host_desc->disable_hotplug(host_set); kfree(host); + + ata_host_stop(host_set); } static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index c4e9e0298122..b18c90582e67 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -122,6 +122,7 @@ static struct ata_port_operations pdc_ata_ops = { .scr_write = pdc_sata_scr_write, .port_start = pdc_port_start, .port_stop = pdc_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info pdc_port_info[] = { diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index dfd362104717..1383e8a28d72 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c @@ -536,6 +536,8 @@ static void qs_host_stop(struct ata_host_set *host_set) writeb(0, mmio_base + QS_HCT_CTRL); /* disable host interrupts */ writeb(QS_CNFG3_GSRST, mmio_base + QS_HCF_CNFG3); /* global reset */ + + ata_host_stop(host_set); } static void qs_host_init(unsigned int chip_id, struct ata_probe_ent *pe) diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 2b2ff48be396..238580d244e6 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -161,6 +161,7 @@ static struct ata_port_operations sil_ops = { .scr_write = sil_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info sil_port_info[] = { diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index 5105ddd08447..e418b89c6b9d 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c @@ -114,6 +114,7 @@ static struct ata_port_operations sis_ops = { .scr_write = sis_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info sis_port_info = { diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 05075bd3a893..edef1fa969fc 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c @@ -313,6 +313,7 @@ static struct ata_port_operations k2_sata_ops = { .scr_write = k2_sata_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base) diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index 70118650c461..140cea05de3f 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c @@ -245,6 +245,8 @@ static void pdc20621_host_stop(struct ata_host_set *host_set) iounmap(dimm_mmio); kfree(hpriv); + + ata_host_stop(host_set); } static int pdc_port_start(struct ata_port *ap) diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index 0bff4f475f26..a71fb54eebd3 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c @@ -113,6 +113,7 @@ static struct ata_port_operations uli_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info uli_port_info = { diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index 3a7830667277..f43183c19a12 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c @@ -134,6 +134,7 @@ static struct ata_port_operations svia_sata_ops = { .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static struct ata_port_info svia_port_info = { diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2c28f0ad73c2..f67c34330ae9 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -230,6 +230,7 @@ static struct ata_port_operations vsc_sata_ops = { .scr_write = vsc_sata_scr_write, .port_start = ata_port_start, .port_stop = ata_port_stop, + .host_stop = ata_host_stop, }; static void __devinit vsc_sata_setup_port(struct ata_ioports *port, unsigned long base) -- cgit v1.2.2 From 5d9e4ea55ae19f9083b9c2c97cc912b823ee7ab4 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 27 May 2005 07:36:17 -0700 Subject: ide-cd: revert DMA mask test change The change to require the DMA length to be only word-aligned was not safe. --- drivers/ide/ide-cd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index f0bd242e030f..78e3e7b24d7d 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1932,8 +1932,11 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) /* * check if dma is safe + * + * NOTE! The "len" and "addr" checks should possibly have + * separate masks. */ - if ((rq->data_len & 3) || (addr & mask)) + if ((rq->data_len & mask) || (addr & mask)) info->dma = 0; } -- cgit v1.2.2 From 88c1834633341bbb94e315433067496338bff4ad Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 27 May 2005 13:40:53 +0100 Subject: [PATCH] remove non-cleanroom pwc driver compression The original pwc author raised some questions about the reverse engineering of the decompressor algorithms used in the pwc driver. Having done some detailed investigation it appears those concerns that clean room policy was not followed are reasonable. I've also had a friendly discussion with Philips to ask their view on this. This removes the problem items of code which reduces the pwc functionality in the kernel a little but leaves all the framework for setup that will be needed for decompressors in user space (where they eventually belong). This change set is designed to be the minimal risk change set given that 2.6.12 is hopefully close to hand, with a view to merging the much updated pwc code in 2.6.13 series kernels. Someone else can then redo the decompressors properly (clean room) in user space. Note that while its easy to say that it should have been caught earlier, but the violation was really only obvious to someone who had access to both the proprietary source and the 'GPL' source. --- drivers/usb/media/pwc/Makefile | 2 +- drivers/usb/media/pwc/pwc-ctrl.c | 12 +- drivers/usb/media/pwc/pwc-dec1.c | 42 -- drivers/usb/media/pwc/pwc-dec1.h | 36 - drivers/usb/media/pwc/pwc-dec23.c | 623 ------------------ drivers/usb/media/pwc/pwc-dec23.h | 58 -- drivers/usb/media/pwc/pwc-if.c | 9 +- drivers/usb/media/pwc/pwc-kiara.c | 573 ---------------- drivers/usb/media/pwc/pwc-timon.c | 1130 -------------------------------- drivers/usb/media/pwc/pwc-uncompress.c | 2 + 10 files changed, 14 insertions(+), 2473 deletions(-) delete mode 100644 drivers/usb/media/pwc/pwc-dec1.c delete mode 100644 drivers/usb/media/pwc/pwc-dec1.h delete mode 100644 drivers/usb/media/pwc/pwc-dec23.c delete mode 100644 drivers/usb/media/pwc/pwc-dec23.h (limited to 'drivers') diff --git a/drivers/usb/media/pwc/Makefile b/drivers/usb/media/pwc/Makefile index e0b41ed4407f..2d93a775011a 100644 --- a/drivers/usb/media/pwc/Makefile +++ b/drivers/usb/media/pwc/Makefile @@ -1,6 +1,6 @@ ifneq ($(KERNELRELEASE),) -pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-dec1.o pwc-dec23.o pwc-kiara.o pwc-timon.o +pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o pwc-timon.o pwc-kiara.o obj-$(CONFIG_USB_PWC) += pwc.o diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 42ec468d52d6..3e1e4fe20d85 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c @@ -246,7 +246,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra switch(pdev->type) { case 645: case 646: - pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); +/* pwc_dec1_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ break; case 675: @@ -256,7 +256,7 @@ static inline int set_video_mode_Nala(struct pwc_device *pdev, int size, int fra case 730: case 740: case 750: - pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); +/* pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ break; } } @@ -318,8 +318,8 @@ static inline int set_video_mode_Timon(struct pwc_device *pdev, int size, int fr if (ret < 0) return ret; - if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); +/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) + pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ pdev->cmd_len = 13; memcpy(pdev->cmd_buf, buf, 13); @@ -397,8 +397,8 @@ static inline int set_video_mode_Kiara(struct pwc_device *pdev, int size, int fr if (ret < 0) return ret; - if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) - pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); +/* if (pChoose->bandlength > 0 && pdev->vpalette != VIDEO_PALETTE_RAW) + pwc_dec23_init(pdev->type, pdev->release, buf, pdev->decompress_data); */ pdev->cmd_len = 12; memcpy(pdev->cmd_buf, buf, 12); diff --git a/drivers/usb/media/pwc/pwc-dec1.c b/drivers/usb/media/pwc/pwc-dec1.c deleted file mode 100644 index 57d03d9178f6..000000000000 --- a/drivers/usb/media/pwc/pwc-dec1.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Linux driver for Philips webcam - Decompression for chipset version 1 - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - - -#include "pwc-dec1.h" - - -void pwc_dec1_init(int type, int release, void *buffer, void *table) -{ - -} - -void pwc_dec1_exit(void) -{ - - - -} - diff --git a/drivers/usb/media/pwc/pwc-dec1.h b/drivers/usb/media/pwc/pwc-dec1.h deleted file mode 100644 index a7ffd9c45a2c..000000000000 --- a/drivers/usb/media/pwc/pwc-dec1.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Linux driver for Philips webcam - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - - - -#ifndef PWC_DEC1_H -#define PWC_DEC1_H - -void pwc_dec1_init(int type, int release, void *buffer, void *private_data); -void pwc_dec1_exit(void); - -#endif - - - diff --git a/drivers/usb/media/pwc/pwc-dec23.c b/drivers/usb/media/pwc/pwc-dec23.c deleted file mode 100644 index 98fa3f7a9eff..000000000000 --- a/drivers/usb/media/pwc/pwc-dec23.c +++ /dev/null @@ -1,623 +0,0 @@ -/* Linux driver for Philips webcam - Decompression for chipset version 2 et 3 - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "pwc-timon.h" -#include "pwc-kiara.h" -#include "pwc-dec23.h" -#include "pwc-ioctl.h" - -#include - -/**** - * - * - * - */ - - -static void fill_table_a000(unsigned int *p) -{ - static unsigned int initial_values[12] = { - 0xFFAD9B00, 0xFFDDEE00, 0x00221200, 0x00526500, - 0xFFC21E00, 0x003DE200, 0xFF924B80, 0xFFD2A300, - 0x002D5D00, 0x006DB480, 0xFFED3E00, 0x0012C200 - }; - static unsigned int values_derivated[12] = { - 0x0000A4CA, 0x00004424, 0xFFFFBBDC, 0xFFFF5B36, - 0x00007BC4, 0xFFFF843C, 0x0000DB69, 0x00005ABA, - 0xFFFFA546, 0xFFFF2497, 0x00002584, 0xFFFFDA7C - }; - unsigned int temp_values[12]; - int i,j; - - memcpy(temp_values,initial_values,sizeof(initial_values)); - for (i=0;i<256;i++) - { - for (j=0;j<12;j++) - { - *p++ = temp_values[j]; - temp_values[j] += values_derivated[j]; - } - } -} - -static void fill_table_d000(unsigned char *p) -{ - int bit,byte; - - for (bit=0; bit<8; bit++) - { - unsigned char bitpower = 1<=1 && k<3) - bit=(table[0]>>15)&7; - else if (k>=3 && k<6) - bit=(table[0]>>12)&7; - else if (k>=6 && k<10) - bit=(table[0]>>9)&7; - else if (k>=10 && k<13) - bit=(table[0]>>6)&7; - else if (k>=13 && k<15) - bit=(table[0]>>3)&7; - else - bit=(table[0])&7; - if (k == 0) - *(unsigned char *)p8++ = 8; - else - *(unsigned char *)p8++ = j - bit; - *(unsigned char *)p8++ = bit; - - pw = 1<xx + pdev->yy) - * - */ -static void fill_table_dc00_d800(unsigned int precision, unsigned int *pdc00, unsigned int *pd800) -{ - int i; - unsigned int offset1, offset2; - - for(i=0,offset1=0x4000, offset2=0; i<256 ; i++,offset1+=0x7BC4, offset2+=0x7BC4) - { - unsigned int msb = offset1 >> 15; - - if ( msb > 255) - { - if (msb) - msb=0; - else - msb=255; - } - - *pdc00++ = msb << precision; - *pd800++ = offset2; - } - -} - -/* - * struct { - * unsigned char op; // operation to execute - * unsigned char bits; // bits use to perform operation - * unsigned char offset1; // offset to add to access in the table_0004 % 16 - * unsigned char offset2; // offset to add to access in the table_0004 - * } - * - */ -static unsigned int table_ops[] = { -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x30, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x10, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x01,0x70, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x20, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x00, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x10, 0x00,0x06,0x02,0x50, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x01,0x60, 0x01,0x00,0x00,0x00, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x00, 0x00,0x04,0x01,0x50, 0x00,0x05,0x02,0x40, -0x02,0x00,0x00,0x00, 0x00,0x03,0x01,0x40, 0x00,0x05,0x03,0x40, 0x01,0x00,0x00,0x00 -}; - -/* - * TODO: multiply by 4 all values - * - */ -static unsigned int MulIdx[256] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, - 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, - 6, 7, 8, 9, 7,10,11, 8, 8,11,10, 7, 9, 8, 7, 6, - 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, 4, 5, 5, 4, - 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3, 0, 2, - 0, 3, 3, 0, 1, 2, 2, 1, 2, 1, 1, 2, 3, 0, 0, 3, - 0, 1, 2, 3, 3, 2, 1, 0, 3, 2, 1, 0, 0, 1, 2, 3, - 1, 1, 1, 1, 3, 3, 3, 3, 0, 0, 0, 0, 2, 2, 2, 2, - 7,10,11, 8, 9, 8, 7, 6, 6, 7, 8, 9, 8,11,10, 7, - 4, 5, 5, 4, 5, 4, 4, 5, 5, 4, 4, 5, 4, 5, 5, 4, - 7, 9, 6, 8,10, 8, 7,11,11, 7, 8,10, 8, 6, 9, 7, - 1, 3, 0, 2, 2, 0, 3, 1, 2, 0, 3, 1, 1, 3, 0, 2, - 1, 2, 2, 1, 3, 0, 0, 3, 0, 3, 3, 0, 2, 1, 1, 2, -10, 8, 7,11, 8, 6, 9, 7, 7, 9, 6, 8,11, 7, 8,10 -}; - - - -void pwc_dec23_init(int type, int release, unsigned char *mode, void *data) -{ - int flags; - struct pwc_dec23_private *pdev = data; - release = release; - - switch (type) - { - case 720: - case 730: - case 740: - case 750: - flags = mode[2]&0x18; /* our: flags = 8, mode[2]==e8 */ - if (flags==8) - pdev->zz = 7; - else if (flags==0x10) - pdev->zz = 8; - else - pdev->zz = 6; - flags = mode[2]>>5; /* our: 7 */ - - fill_table_color(flags, (unsigned int *)KiaraRomTable, pdev->table_0004, pdev->table_8004); - break; - - - case 675: - case 680: - case 690: - flags = mode[2]&6; - if (flags==2) - pdev->zz = 7; - else if (flags==4) - pdev->zz = 8; - else - pdev->zz = 6; - flags = mode[2]>>3; - - fill_table_color(flags, (unsigned int *)TimonRomTable, pdev->table_0004, pdev->table_8004); - break; - - default: - /* Not supported */ - return; - } - - /* * * * ** */ - pdev->xx = 8 - pdev->zz; - pdev->yy = 15 - pdev->xx; - pdev->zzmask = 0xFF>>pdev->xx; - //pdev->zzmask = (1U<zz)-1; - - - fill_table_dc00_d800(pdev->xx + pdev->yy, pdev->table_dc00, pdev->table_d800); - fill_table_a000(pdev->table_a004); - fill_table_d000(pdev->table_d004); -} - - -/* - * To manage the stream, we keep in a 32 bits variables, - * the next bits in the stream. fill_reservoir() add to - * the reservoir at least wanted nbits. - * - * - */ -#define fill_nbits(reservoir,nbits_in_reservoir,stream,nbits_wanted) do { \ - while (nbits_in_reservoir>= nbits_wanted; \ - nbits_in_reservoir -= nbits_wanted; \ -} while(0); - - - -static void DecompressBand23(const struct pwc_dec23_private *pdev, - const unsigned char *rawyuv, - unsigned char *planar_y, - unsigned char *planar_u, - unsigned char *planar_v, - unsigned int image_x, /* aka number of pixels wanted ??? */ - unsigned int pixels_per_line, /* aka number of pixels per line */ - int flags) -{ - - - unsigned int reservoir, nbits_in_reservoir; - int first_4_bits; - unsigned int bytes_per_channel; - int line_size; /* size of the line (4Y+U+V) */ - int passes; - const unsigned char *ptable0004, *ptable8004; - - int even_line; - unsigned int temp_colors[16]; - int nblocks; - - const unsigned char *stream; - unsigned char *dest_y, *dest_u=NULL, *dest_v=NULL; - unsigned int offset_to_plane_u, offset_to_plane_v; - - int i; - - - reservoir = 0; - nbits_in_reservoir = 0; - stream = rawyuv+1; /* The first byte of the stream is skipped */ - even_line = 1; - - get_nbits(reservoir,nbits_in_reservoir,stream,4,first_4_bits); - - line_size = pixels_per_line*3; - - for (passes=0;passes<2;passes++) - { - if (passes==0) - { - bytes_per_channel = pixels_per_line; - dest_y = planar_y; - nblocks = image_x/4; - } - else - { - /* Format planar: All Y, then all U, then all V */ - bytes_per_channel = pixels_per_line/2; - dest_u = planar_u; - dest_v = planar_v; - dest_y = dest_u; - nblocks = image_x/8; - } - - offset_to_plane_u = bytes_per_channel*2; - offset_to_plane_v = bytes_per_channel*3; - /* - printf("bytes_per_channel = %d\n",bytes_per_channel); - printf("offset_to_plane_u = %d\n",offset_to_plane_u); - printf("offset_to_plane_v = %d\n",offset_to_plane_v); - */ - - while (nblocks-->0) - { - unsigned int gray_index; - - fill_nbits(reservoir,nbits_in_reservoir,stream,16); - gray_index = reservoir & pdev->zzmask; - reservoir >>= pdev->zz; - nbits_in_reservoir -= pdev->zz; - - fill_nbits(reservoir,nbits_in_reservoir,stream,2); - - if ( (reservoir & 3) == 0) - { - reservoir>>=2; - nbits_in_reservoir-=2; - for (i=0;i<16;i++) - temp_colors[i] = pdev->table_dc00[gray_index]; - - } - else - { - unsigned int channel_v, offset1; - - /* swap bit 0 and 2 of offset_OR */ - channel_v = ((reservoir & 1) << 2) | (reservoir & 2) | ((reservoir & 4)>>2); - reservoir>>=3; - nbits_in_reservoir-=3; - - for (i=0;i<16;i++) - temp_colors[i] = pdev->table_d800[gray_index]; - - ptable0004 = pdev->table_0004 + (passes*16384) + (first_4_bits*1024) + (channel_v*128); - ptable8004 = pdev->table_8004 + (passes*4096) + (first_4_bits*256) + (channel_v*32); - - offset1 = 0; - while(1) - { - unsigned int index_in_table_ops, op, rows=0; - fill_nbits(reservoir,nbits_in_reservoir,stream,16); - - /* mode is 0,1 or 2 */ - index_in_table_ops = (reservoir&0x3F); - op = table_ops[ index_in_table_ops*4 ]; - if (op == 2) - { - reservoir >>= 2; - nbits_in_reservoir -= 2; - break; /* exit the while(1) */ - } - if (op == 0) - { - unsigned int shift; - - offset1 = (offset1 + table_ops[index_in_table_ops*4+2]) & 0x0F; - shift = table_ops[ index_in_table_ops*4+1 ]; - reservoir >>= shift; - nbits_in_reservoir -= shift; - rows = ptable0004[ offset1 + table_ops[index_in_table_ops*4+3] ]; - } - if (op == 1) - { - /* 10bits [ xxxx xxxx yyyy 000 ] - * yyy => offset in the table8004 - * xxx => offset in the tabled004 - */ - unsigned int mask, shift; - unsigned int col1, row1, total_bits; - - offset1 = (offset1 + ((reservoir>>3)&0x0F)+1) & 0x0F; - - col1 = (reservoir>>7) & 0xFF; - row1 = ptable8004 [ offset1*2 ]; - - /* Bit mask table */ - mask = pdev->table_d004[ (row1<<8) + col1 ]; - shift = ptable8004 [ offset1*2 + 1]; - rows = ((mask << shift) + 0x80) & 0xFF; - - total_bits = row1 + 8; - reservoir >>= total_bits; - nbits_in_reservoir -= total_bits; - } - { - const unsigned int *table_a004 = pdev->table_a004 + rows*12; - unsigned int *poffset = MulIdx + offset1*16; /* 64/4 (int) */ - for (i=0;i<16;i++) - { - temp_colors[i] += table_a004[ *poffset ]; - poffset++; - } - } - } - } -#define USE_SIGNED_INT_FOR_COLOR -#ifdef USE_SIGNED_INT_FOR_COLOR -# define CLAMP(x) ((x)>255?255:((x)<0?0:x)) -#else -# define CLAMP(x) ((x)>255?255:x) -#endif - - if (passes == 0) - { -#ifdef USE_SIGNED_INT_FOR_COLOR - const int *c = temp_colors; -#else - const unsigned int *c = temp_colors; -#endif - unsigned char *d; - - d = dest_y; - for (i=0;i<4;i++,c++) - *d++ = CLAMP((*c) >> pdev->yy); - - d = dest_y + bytes_per_channel; - for (i=0;i<4;i++,c++) - *d++ = CLAMP((*c) >> pdev->yy); - - d = dest_y + offset_to_plane_u; - for (i=0;i<4;i++,c++) - *d++ = CLAMP((*c) >> pdev->yy); - - d = dest_y + offset_to_plane_v; - for (i=0;i<4;i++,c++) - *d++ = CLAMP((*c) >> pdev->yy); - - dest_y += 4; - } - else if (passes == 1) - { -#ifdef USE_SIGNED_INT_FOR_COLOR - int *c1 = temp_colors; - int *c2 = temp_colors+4; -#else - unsigned int *c1 = temp_colors; - unsigned int *c2 = temp_colors+4; -#endif - unsigned char *d; - - d = dest_y; - for (i=0;i<4;i++,c1++,c2++) - { - *d++ = CLAMP((*c1) >> pdev->yy); - *d++ = CLAMP((*c2) >> pdev->yy); - } - c1 = temp_colors+12; - //c2 = temp_colors+8; - d = dest_y + bytes_per_channel; - for (i=0;i<4;i++,c1++,c2++) - { - *d++ = CLAMP((*c1) >> pdev->yy); - *d++ = CLAMP((*c2) >> pdev->yy); - } - - if (even_line) /* Each line, swap u/v */ - { - even_line=0; - dest_y = dest_v; - dest_u += 8; - } - else - { - even_line=1; - dest_y = dest_u; - dest_v += 8; - } - } - - } /* end of while (nblocks-->0) */ - - } /* end of for (passes=0;passes<2;passes++) */ - -} - - -/** - * - * image: size of the image wanted - * view : size of the image returned by the camera - * offset: (x,y) to displayer image in the view - * - * src: raw data - * dst: image output - * flags: PWCX_FLAG_PLANAR - * pdev: private buffer - * bandlength: - * - */ -void pwc_dec23_decompress(const struct pwc_coord *image, - const struct pwc_coord *view, - const struct pwc_coord *offset, - const void *src, - void *dst, - int flags, - const void *data, - int bandlength) -{ - const struct pwc_dec23_private *pdev = data; - unsigned char *pout, *pout_planar_y=NULL, *pout_planar_u=NULL, *pout_planar_v=NULL; - int i,n,stride,pixel_size; - - - if (flags & PWCX_FLAG_BAYER) - { - pout = dst + (view->x * offset->y) + offset->x; - pixel_size = view->x * 4; - } - else - { - n = view->x * view->y; - - /* offset in Y plane */ - stride = view->x * offset->y; - pout_planar_y = dst + stride + offset->x; - - /* offsets in U/V planes */ - stride = (view->x * offset->y)/4 + offset->x/2; - pout_planar_u = dst + n + + stride; - pout_planar_v = dst + n + n/4 + stride; - - pixel_size = view->x * 4; - } - - - for (i=0;iy;i+=4) - { - if (flags & PWCX_FLAG_BAYER) - { - //TODO: - //DecompressBandBayer(pdev,src,pout,image.x,view->x,flags); - src += bandlength; - pout += pixel_size; - } - else - { - DecompressBand23(pdev,src,pout_planar_y,pout_planar_u,pout_planar_v,image->x,view->x,flags); - src += bandlength; - pout_planar_y += pixel_size; - pout_planar_u += view->x; - pout_planar_v += view->x; - } - } -} - -void pwc_dec23_exit(void) -{ - /* Do nothing */ - -} - diff --git a/drivers/usb/media/pwc/pwc-dec23.h b/drivers/usb/media/pwc/pwc-dec23.h deleted file mode 100644 index 5b2aacdefa6c..000000000000 --- a/drivers/usb/media/pwc/pwc-dec23.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Linux driver for Philips webcam - (C) 2004 Luc Saillard (luc@saillard.org) - - NOTE: this version of pwc is an unofficial (modified) release of pwc & pcwx - driver and thus may have bugs that are not present in the original version. - Please send bug reports and support requests to . - The decompression routines have been implemented by reverse-engineering the - Nemosoft binary pwcx module. Caveat emptor. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef PWC_DEC23_H -#define PWC_DEC23_H - -struct pwc_dec23_private -{ - unsigned char xx,yy,zz,zzmask; - - unsigned char table_0004[2*0x4000]; - unsigned char table_8004[2*0x1000]; - unsigned int table_a004[256*12]; - - unsigned char table_d004[8*256]; - unsigned int table_d800[256]; - unsigned int table_dc00[256]; -}; - - -void pwc_dec23_init(int type, int release, unsigned char *buffer, void *private_data); -void pwc_dec23_exit(void); -void pwc_dec23_decompress(const struct pwc_coord *image, - const struct pwc_coord *view, - const struct pwc_coord *offset, - const void *src, - void *dst, - int flags, - const void *data, - int bandlength); - - - -#endif - - - diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index cca47f480a8b..5429ff3b9753 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c @@ -68,8 +68,6 @@ #include "pwc-ioctl.h" #include "pwc-kiara.h" #include "pwc-timon.h" -#include "pwc-dec23.h" -#include "pwc-dec1.h" #include "pwc-uncompress.h" /* Function prototypes and driver templates */ @@ -322,6 +320,7 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) case 730: case 740: case 750: +#if 0 Trace(TRACE_MEMORY,"private_data(%zu)\n",sizeof(struct pwc_dec23_private)); kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); /* Timon & Kiara */ break; @@ -330,6 +329,8 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) /* TODO & FIXME */ kbuf = kmalloc(sizeof(struct pwc_dec23_private), GFP_KERNEL); break; +#endif + ; } if (kbuf == NULL) { Err("Failed to allocate decompress table.\n"); @@ -1131,11 +1132,11 @@ static int pwc_video_close(struct inode *inode, struct file *file) case 730: case 740: case 750: - pwc_dec23_exit(); /* Timon & Kiara */ +/* pwc_dec23_exit(); *//* Timon & Kiara */ break; case 645: case 646: - pwc_dec1_exit(); +/* pwc_dec1_exit(); */ break; } diff --git a/drivers/usb/media/pwc/pwc-kiara.c b/drivers/usb/media/pwc/pwc-kiara.c index 5485800efd83..c498c68bace1 100644 --- a/drivers/usb/media/pwc/pwc-kiara.c +++ b/drivers/usb/media/pwc/pwc-kiara.c @@ -316,576 +316,3 @@ const struct Kiara_table_entry Kiara_table[PSZ_MAX][6][4] = }, }; - -/* - * Rom table for kiara chips - * - * 32 roms tables (one for each resolution ?) - * 2 tables per roms (one for each passes) (Y, and U&V) - * 128 bytes per passes - */ - -const unsigned int KiaraRomTable [8][2][16][8] = -{ - { /* version 0 */ - { /* version 0, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x0000124a,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009292,0x00009292,0x00009493,0x000124db}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x0000a493,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x000124db,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 0, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000001,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000049,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009252,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009292,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009292, - 0x00009492,0x00009493,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009252,0x00009493, - 0x000126dc,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 1 */ - { /* version 1, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009252,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009252, - 0x00009492,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 1, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000049,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000000}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000049,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x0000924a,0x0000924a, - 0x00009492,0x00009493,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 2 */ - { /* version 2, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x0000a49b}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x0001b724,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 2, passes 1 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x0000a49b,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x0001249b,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 3 */ - { /* version 3, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0001b925,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 3, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 4 */ - { /* version 4, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009252,0x00009493, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 4, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000049,0x00000049,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00000249,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 5 */ - { /* version 5, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 5, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x00009252,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 6 */ - { /* version 6, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000126db, - 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 6, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 7 */ - { /* version 7, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x000124db}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 7, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x00009492,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - } -}; - diff --git a/drivers/usb/media/pwc/pwc-timon.c b/drivers/usb/media/pwc/pwc-timon.c index f950a4e5ed96..dee967173d6c 100644 --- a/drivers/usb/media/pwc/pwc-timon.c +++ b/drivers/usb/media/pwc/pwc-timon.c @@ -314,1133 +314,3 @@ const struct Timon_table_entry Timon_table[PSZ_MAX][6][4] = }, }; -/* - * 16 versions: - * 2 tables (one for Y, and one for U&V) - * 16 levels of details per tables - * 8 blocs - */ - -const unsigned int TimonRomTable [16][2][16][8] = -{ - { /* version 0 */ - { /* version 0, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000001,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000001, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000009,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x0000124a,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 0, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000001,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000001, - 0x00000001,0x00000009,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000009,0x00000049,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000009,0x00000049,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 1 */ - { /* version 1, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000001,0x00000001, - 0x00000001,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000009,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 1, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000001,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000001,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000049,0x00000249,0x00000009,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00000049,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009252,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 2 */ - { /* version 2, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000009,0x00000009, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009252,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009252, - 0x00009492,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 2, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000009, - 0x00000049,0x00000009,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000000}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000049,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x0000024a,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009292,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009292,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x0000924a,0x0000924a, - 0x00009492,0x00009493,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 3 */ - { /* version 3, passes 0 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000001}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000049,0x00000249, - 0x00000249,0x00000249,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00009252, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009292,0x0000a49b,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 3, passes 1 */ - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000}, - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000001,0x00000000}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00000049,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00000001}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x00009292,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009252,0x00009292,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009292, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 4 */ - { /* version 4, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x0000a49b}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x0001b724,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 4, passes 1 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x0000a49b,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x0001249b,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 5 */ - { /* version 5, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x0000124a,0x00001252,0x00009292}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x0000124a,0x00009292,0x00009292,0x00009493}, - {0x00000000,0x00000000,0x00000249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000126dc,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 5, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x00009493,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x000124db,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009493,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 6 */ - { /* version 6, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x0000124a,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0001b925,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 6, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x0000a49b,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 7 */ - { /* version 7, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x000124db,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0001249b,0x000126dc,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000126dc,0x0001b724,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x0002496e}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x0001c96e,0x0002496e}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x0002496d,0x00025bb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 7, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000136e4,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00012492,0x000126db, - 0x0001b724,0x0001b925,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 8 */ - { /* version 8, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009292,0x00009493,0x0000a49b,0x000124db}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x000124db,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000136e4}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000136e4,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x0001b925}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x000126dc,0x0001b724,0x0001b92d,0x0001c92d}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000126dc,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x00024b76,0x00024b77}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x00024b76,0x00025bbf}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0001c92d,0x00024b76,0x00025bbf}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x0001b724,0x00024b6d,0x0002ddb6,0x0002efff}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 8, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x0001b724,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x0002496d,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 9 */ - { /* version 9, passes 0 */ - {0x00000000,0x00000000,0x00000049,0x00000049, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000249,0x00000249,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x0000124a,0x00009252,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009252,0x00009493, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 9, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000049, - 0x00000009,0x00000009,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000049,0x00000049,0x00000009,0x00000009}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00000249,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009493,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000124db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 10 */ - { /* version 10, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00000249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x00009493,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x000124db,0x000124db,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0001249b,0x000126dc,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000126dc,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009252,0x0000a49b, - 0x000124db,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000126dc,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x000136e4,0x0002496d,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 10, passes 1 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000049,0x00000049,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00000249,0x00000049,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x00009252,0x0000024a,0x00000049}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009493,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009252, - 0x00009492,0x00009493,0x00001252,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009493,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x00009492,0x00009493,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009493,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009252,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 11 */ - { /* version 11, passes 0 */ - {0x00000000,0x00000000,0x00000249,0x00000249, - 0x00000249,0x00000249,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009492,0x0000a49b,0x0000a49b,0x00009292}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000136e4}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 11, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00000249, - 0x00000249,0x00000249,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009252,0x00009252,0x0000024a,0x0000024a}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x0000a49b,0x00009292,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 12 */ - { /* version 12, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x0000a493,0x0000a49b,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x0001b724}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001b925,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000126db, - 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 12, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x00001249,0x00009292, - 0x00009492,0x00009252,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000124db,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x000136e4,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x000126db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 13 */ - { /* version 13, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x00009252,0x00009292,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0001249b,0x000126dc,0x000126dc,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x000136e4,0x0001b725,0x000124db}, - {0x00000000,0x00000000,0x00009292,0x0000a49b, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000136e4,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x00024924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 13, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x00009492,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0000a49b,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000124db,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000124db,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000136db, - 0x0001b724,0x000126dc,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000126dc,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 14 */ - { /* version 14, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x0000924a, - 0x00009292,0x00009493,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00001249,0x0000a49b, - 0x0000a493,0x000124db,0x000126dc,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x0000a49b}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x000136e4,0x0001b725,0x000124db}, - {0x00000000,0x00000000,0x00009292,0x000124db, - 0x000126dc,0x0001b724,0x0001b92d,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001c92d,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x0001c92d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x0002496d,0x00024b76,0x00024b77}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x00024924,0x0002db6d,0x00036db6,0x0002efff}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 14, passes 1 */ - {0x00000000,0x00000000,0x00001249,0x00001249, - 0x0000124a,0x0000124a,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x00009493, - 0x0000a493,0x00009292,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x0000a49b,0x00001252,0x00001252}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000136e4,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x000136e4,0x00009493,0x00009292}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x0000a49b,0x00009493}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001b724,0x000136e4,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000124db,0x0000a49b}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b724,0x000136e4,0x000126dc,0x000124db}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x0001c924,0x0001b724,0x000136e4,0x000126dc}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - }, - { /* version 15 */ - { /* version 15, passes 0 */ - {0x00000000,0x00000000,0x00001249,0x00009493, - 0x0000a493,0x0000a49b,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0001249b,0x000126dc,0x000136e4,0x000124db}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x000126dc,0x0001b724,0x0001b725,0x000126dc}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x0001b724,0x0001b92d,0x000126dc}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x000136e4,0x0001b925,0x0001c96e,0x000136e4}, - {0x00000000,0x00000000,0x00009492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000124db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b724}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b724,0x0001c92d,0x0001c96e,0x0001b925}, - {0x00000000,0x00000000,0x0000a492,0x000126db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x0001c92d,0x00024b76,0x0001c92d}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001b924,0x0002496d,0x00024b76,0x0002496e}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0002496d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x00024b6d,0x00025bb6,0x00024b77}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x0001c924,0x00024b6d,0x0002ddb6,0x00025bbf}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x00024924,0x0002db6d,0x00036db6,0x0002efff}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - }, - { /* version 15, passes 1 */ - {0x00000000,0x00000000,0x0000924a,0x0000924a, - 0x00009292,0x00009292,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x0000a49b, - 0x0000a493,0x000124db,0x00009292,0x00009292}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000124db,0x0001b724,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000126dc,0x0001b724,0x00009493,0x00009493}, - {0x00000000,0x00000000,0x0000924a,0x000124db, - 0x000136e4,0x0001b724,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009292,0x000136db, - 0x0001b724,0x0001b724,0x0000a49b,0x0000a49b}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001c924,0x0001b724,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x00009492,0x000136db, - 0x0001c924,0x0001b724,0x000124db,0x000124db}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b724,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x000126dc,0x000126dc}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x000136e4,0x000136e4}, - {0x00000000,0x00000000,0x0000a492,0x000136db, - 0x0001c924,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00012492,0x000136db, - 0x0001c924,0x0001b925,0x0001b725,0x0001b724}, - {0x00000000,0x00000000,0x00012492,0x0001b6db, - 0x00024924,0x0002496d,0x0001b92d,0x0001b925}, - {0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000,0x00000000,0x00000000} - } - } -}; diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c index c062e43b3ac5..c596083f06ba 100644 --- a/drivers/usb/media/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c @@ -122,6 +122,7 @@ int pwc_decompress(struct pwc_device *pdev) switch (pdev->type) { +#if 0 case 675: case 680: case 690: @@ -137,6 +138,7 @@ int pwc_decompress(struct pwc_device *pdev) case 645: case 646: /* TODO & FIXME */ +#endif return -ENXIO; /* No such device or address: missing decompressor */ break; } -- cgit v1.2.2 From 25be5e6ccc5c9cab77012fabbb72520f9b6e4618 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 27 May 2005 04:21:50 -0400 Subject: [PATCH] VIA IRQ quirk Delete quirk_via_bridge(), restore quirk_via_irqpic() -- but now improved to be invoked upon device ENABLE, and now only for VIA devices -- not all devices behind VIA bridges. Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/pci_irq.c | 4 ---- drivers/pci/quirks.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 12b0eea63407..8093f2e00321 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -391,7 +391,6 @@ acpi_pci_irq_enable ( u8 pin = 0; int edge_level = ACPI_LEVEL_SENSITIVE; int active_high_low = ACPI_ACTIVE_LOW; - extern int via_interrupt_line_quirk; char *link = NULL; ACPI_FUNCTION_TRACE("acpi_pci_irq_enable"); @@ -444,9 +443,6 @@ acpi_pci_irq_enable ( } } - if (via_interrupt_line_quirk) - pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq & 15); - dev->irq = acpi_register_gsi(irq, edge_level, active_high_low); printk(KERN_INFO PREFIX "PCI Interrupt %s[%c] -> ", diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 026aa04669a2..afc9d29acd8a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "pci.h" /* Deal with broken BIOS'es that neglect to enable passive release, @@ -467,9 +468,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, * non-x86 architectures (yes Via exists on PPC among other places), * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get * interrupts delivered properly. - * - * TODO: When we have device-specific interrupt routers, - * quirk_via_irqpic will go away from quirks. */ /* @@ -494,6 +492,29 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); +static void __devinit quirk_via_irqpic(struct pci_dev *dev) +{ + u8 irq, new_irq; + +#ifdef CONFIG_X86_IO_APIC + if (nr_ioapics && !skip_ioapic_setup) + return; +#endif +#ifdef CONFIG_ACPI + if (acpi_irq_model != ACPI_IRQ_MODEL_PIC) + return; +#endif + new_irq = dev->irq & 0xf; + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); + if (new_irq != irq) { + printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n", + pci_name(dev), irq, new_irq); + udelay(15); /* unknown if delay really needed */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); + } +} +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic); + /* * PIIX3 USB: We have to disable USB interrupts that are * hardwired to PIRQD# and may be shared with an @@ -683,19 +704,6 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb ); -/* - * VIA northbridges care about PCI_INTERRUPT_LINE - */ -int via_interrupt_line_quirk; - -static void __devinit quirk_via_bridge(struct pci_dev *pdev) -{ - if(pdev->devfn == 0) { - printk(KERN_INFO "PCI: Via IRQ fixup\n"); - via_interrupt_line_quirk = 1; - } -} -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_bridge ); /* * Serverworks CSB5 IDE does not fully support native mode -- cgit v1.2.2 From 9920e91450ee9b373dd4924f79d287a267b8f6a3 Mon Sep 17 00:00:00 2001 From: Alexander Nyberg Date: Fri, 27 May 2005 12:27:05 +0200 Subject: [PATCH] Fixup VIA IRQ quirk quirk_via_irqpic can't be __devinit for swsuspend Signed-off-by: Alexander Nyberg Signed-off-by: Linus Torvalds --- drivers/pci/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index afc9d29acd8a..637e9493034b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -492,7 +492,7 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); -static void __devinit quirk_via_irqpic(struct pci_dev *dev) +static void quirk_via_irqpic(struct pci_dev *dev) { u8 irq, new_irq; -- cgit v1.2.2 From 3e11c3ce0a4ce3d30802babccb0e5f881778ccf1 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 27 May 2005 04:53:27 -0400 Subject: [PATCH] ACPI build fix Fix 2.6.12 CONFIG_ACPI=n build regression. CONFIG_ACPI_BOOT shall be set only if CONFIG_ACPI. Signed-off-by: Len Brown Signed-off-by: Linus Torvalds --- drivers/acpi/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 0400a52d5085..670fdb5142d1 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -40,13 +40,12 @@ config ACPI available at: +if ACPI + config ACPI_BOOT bool - depends on ACPI || X86_HT default y -if ACPI - config ACPI_INTERPRETER bool depends on !IA64_SGI_SN -- cgit v1.2.2 From 7003c05d77593f567e9940e68a944d846228fd7a Mon Sep 17 00:00:00 2001 From: "domen@coderock.org" Date: Fri, 8 Apr 2005 09:53:09 +0200 Subject: [PATCH] drivers/scsi/sata_vsc: add #include req'd for DMA_32BIT_MASK constant The previous patch did not compile cleanly on all architectures so here's a fixed one which #includes . Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling pci_set_dma_mask() or pci_set_consistent_dma_mask() This patch includes dma-mapping.h explicitly because it caused errors on some architectures otherwise. See http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for details Signed-off-by: Tobias Klauser Signed-off-by: Domen Puncer diff -puN drivers/scsi/sata_vsc.c~dma_mask-drivers_scsi_sata_vsc drivers/scsi/sata_vsc.c --- drivers/scsi/sata_vsc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index 2c28f0ad73c2..05e0130a9f3c 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "scsi.h" #include #include -- cgit v1.2.2 From 87507cfdd2cde397c9da8f6e7ec23b2b47ec53d6 Mon Sep 17 00:00:00 2001 From: "domen@coderock.org" Date: Fri, 8 Apr 2005 09:53:06 +0200 Subject: [PATCH] drivers/scsi/ahci: add #include req'd for the DMA_{64,32}BIT_MASK constants The previous patch did not compile cleanly on all architectures so here's a fixed one which #includes . Use the DMA_{64,32}BIT_MASK constants from dma-mapping.h when calling pci_set_dma_mask() or pci_set_consistent_dma_mask() This patch includes dma-mapping.h explicitly because it caused errors on some architectures otherwise. See http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for details Signed-off-by: Tobias Klauser Signed-off-by: Domen Puncer diff -puN drivers/scsi/ahci.c~dma_mask-drivers_scsi_ahci drivers/scsi/ahci.c --- drivers/scsi/ahci.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index da5bd33d982d..8263b3a5d8d7 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "scsi.h" #include #include -- cgit v1.2.2 From 271b74d0b886301f297407dd7ae11b99607f8089 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 28 May 2005 02:11:06 -0500 Subject: Input: Fix a warning in psmouse-base.c Signed-off-by: Andrew Morton Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index cd8509549eac..c9f8e16ca578 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -972,7 +972,7 @@ static int psmouse_set_maxproto(const char *val, struct kernel_param *kp) return -EINVAL; if (!strncmp(val, "any", 3)) { - *((unsigned int *)kp->arg) = -1UL; + *((unsigned int *)kp->arg) = -1U; return 0; } -- cgit v1.2.2 From 668d1e6093110f7534e661e2ff43d54c74659b6d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 28 May 2005 02:11:12 -0500 Subject: Input: This patch adds dummy gameport_register_port, gameport_unregister_port and gameport_set_phys functions to gameport.h for the case when a driver can't use gameport. This fixes the compilation of some OSS drivers with GAMEPORT=n without the need to #if inside every single driver. This patch also removes the non-working and now obsolete SOUND_GAMEPORT. This patch is also an alternative solution for ALSA drivers with similar problems (but #if's inside the drivers might have the advantage of saving some more bytes of gameport is not available). The only user-visible change is that for GAMEPORT=m the affected OSS drivers are now allowed to be built statically (but they won't have gameport support). Signed-off-by: Adrian Bunk Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/gameport/Kconfig | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'drivers') diff --git a/drivers/input/gameport/Kconfig b/drivers/input/gameport/Kconfig index 6282f460aba0..1d93f5092904 100644 --- a/drivers/input/gameport/Kconfig +++ b/drivers/input/gameport/Kconfig @@ -68,23 +68,3 @@ config GAMEPORT_CS461X depends on PCI endif - -# Yes, SOUND_GAMEPORT looks a bit odd. Yes, it ends up being turned on -# in every .config. Please don't touch it. It is here to handle an -# unusual dependency between GAMEPORT and sound drivers. -# -# Some sound drivers call gameport functions. If GAMEPORT is -# not selected, empty stubs are provided for the functions and all is -# well. -# If GAMEPORT is built in, everything is fine. -# If GAMEPORT is a module, however, it would need to be loaded for the -# sound driver to be able to link properly. Therefore, the sound -# driver must be a module as well in that case. Since there's no way -# to express that directly in Kconfig, we use SOUND_GAMEPORT to -# express it. SOUND_GAMEPORT boils down to "if GAMEPORT is 'm', -# anything that depends on SOUND_GAMEPORT must be 'm' as well. if -# GAMEPORT is 'y' or 'n', it can be anything". -config SOUND_GAMEPORT - tristate - default m if GAMEPORT=m - default y -- cgit v1.2.2 From 39fa58007a54b09c91cb7bf3ce3cfcc4957f92ff Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sat, 28 May 2005 02:11:16 -0500 Subject: Input: Add a missing KERN_INFO message designation, fix behavior when only a keyboard part of the controller is detected. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index f64867808fea..0327472393de 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -227,7 +227,7 @@ static int i8042_pnp_init(void) int result_kbd, result_aux; if (i8042_nopnp) { - printk("i8042: PNP detection disabled\n"); + printk(KERN_INFO "i8042: PNP detection disabled\n"); return 0; } @@ -265,7 +265,7 @@ static int i8042_pnp_init(void) i8042_pnp_kbd_irq = i8042_kbd_irq; } - if (result_aux > 0 && !i8042_pnp_aux_irq) { + if (!i8042_pnp_aux_irq) { printk(KERN_WARNING "PNP: PS/2 controller doesn't have AUX irq; using default %#x\n", i8042_aux_irq); i8042_pnp_aux_irq = i8042_aux_irq; } -- cgit v1.2.2 From be15692310ec0e93998d763931089cb21386a058 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sat, 28 May 2005 02:11:19 -0500 Subject: Input: Remove (now) unused variable in i8042.c Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 8e63e464d361..8f5b123e2ebc 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -802,8 +802,6 @@ static int i8042_controller_init(void) */ static void i8042_controller_reset(void) { - unsigned char param; - /* * Reset the controller if requested. */ -- cgit v1.2.2 From 2673c836ab9a44b02d45ae5c1c44c03df138dba4 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sat, 28 May 2005 02:11:27 -0500 Subject: Input: Only write the CTR in i8042 resume function. Reading it is wrong, since it may (will) contain nonsensical data. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042.c | 48 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 8f5b123e2ebc..5900de3c3f4f 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -698,6 +698,26 @@ static void i8042_timer_func(unsigned long data) i8042_interrupt(0, NULL, NULL); } +static int i8042_ctl_test(void) +{ + unsigned char param; + + if (!i8042_reset) + return 0; + + if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { + printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); + return -1; + } + + if (param != I8042_RET_CTL_TEST) { + printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", + param, I8042_RET_CTL_TEST); + return -1; + } + + return 0; +} /* * i8042_controller init initializes the i8042 controller, and, @@ -719,21 +739,8 @@ static int i8042_controller_init(void) return -1; } - if (i8042_reset) { - - unsigned char param; - - if (i8042_command(¶m, I8042_CMD_CTL_TEST)) { - printk(KERN_ERR "i8042.c: i8042 controller self test timeout.\n"); - return -1; - } - - if (param != I8042_RET_CTL_TEST) { - printk(KERN_ERR "i8042.c: i8042 controller selftest failed. (%#x != %#x)\n", - param, I8042_RET_CTL_TEST); - return -1; - } - } + if (i8042_ctl_test()) + return -1; /* * Save the CTR for restoral on unload / reboot. @@ -806,9 +813,7 @@ static void i8042_controller_reset(void) * Reset the controller if requested. */ - if (i8042_reset) - if (i8042_command(¶m, I8042_CMD_CTL_TEST)) - printk(KERN_ERR "i8042.c: i8042 controller reset timeout.\n"); + i8042_ctl_test(); /* * Disable MUX mode if present. @@ -920,8 +925,11 @@ static int i8042_resume(struct device *dev, u32 level) if (level != RESUME_ENABLE) return 0; - if (i8042_controller_init()) { - printk(KERN_ERR "i8042: resume failed\n"); + if (i8042_ctl_test()) + return -1; + + if (i8042_command(&i8042_ctr, I8042_CMD_CTL_WCTR)) { + printk(KERN_ERR "i8042: Can't write CTR\n"); return -1; } -- cgit v1.2.2 From 5a72afc03ccc29458502cf032f5c34e5ee004ae7 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 28 May 2005 02:11:32 -0500 Subject: Input: Tone down the severity of a printk() in i386/ia64 arch code for i386, it's printed on many machines and usually is not a cause for worry. Signed-off-by: Dmitry Torokhov Signed-off-by: Vojtech Pavlik --- drivers/input/serio/i8042-x86ia64io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 0327472393de..819e47754dab 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -241,7 +241,7 @@ static int i8042_pnp_init(void) #if defined(__ia64__) return -ENODEV; #else - printk(KERN_WARNING "PNP: No PS/2 controller found. Probing ports directly.\n"); + printk(KERN_INFO "PNP: No PS/2 controller found. Probing ports directly.\n"); return 0; #endif } -- cgit v1.2.2 From 74af42bb729651855f78ea27498250724689130e Mon Sep 17 00:00:00 2001 From: Kurt Garloff Date: Sat, 28 May 2005 02:11:38 -0500 Subject: Input: Avoid double unregistering of i8042 PnP driver. This can happen when no i8042 controller (not PnP, not legacy) is present. From: Kurt Garloff Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index 819e47754dab..f4c5f7745422 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -215,11 +215,15 @@ static struct pnp_driver i8042_pnp_aux_driver = { static void i8042_pnp_exit(void) { - if (i8042_pnp_kbd_registered) + if (i8042_pnp_kbd_registered) { + i8042_pnp_kbd_registered = 0; pnp_unregister_driver(&i8042_pnp_kbd_driver); + } - if (i8042_pnp_aux_registered) + if (i8042_pnp_aux_registered) { + i8042_pnp_aux_registered = 0; pnp_unregister_driver(&i8042_pnp_aux_driver); + } } static int i8042_pnp_init(void) -- cgit v1.2.2 From 7741e9317137a7456baa9c09ad8308c80c23b8db Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sat, 28 May 2005 02:11:42 -0500 Subject: Input: Workaround for Sunrex K8561 IR Keyboard/Mouse. The mouse sends an incorrect ID and wasn't recognized. Reported-by: Stefan Seyfried Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/psmouse-base.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index c9f8e16ca578..019034b21a0b 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -518,13 +518,16 @@ static int psmouse_probe(struct psmouse *psmouse) /* * First, we check if it's a mouse. It should send 0x00 or 0x03 * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. + * Sunrex K8561 IR Keyboard/Mouse reports 0xff on second and subsequent + * ID queries, probably due to a firmware bug. */ param[0] = 0xa5; if (ps2_command(ps2dev, param, PSMOUSE_CMD_GETID)) return -1; - if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) + if (param[0] != 0x00 && param[0] != 0x03 && + param[0] != 0x04 && param[0] != 0xff) return -1; /* -- cgit v1.2.2 From f24949e8e0b9bed223ad9a435bf37e91ee8d0db7 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sat, 28 May 2005 02:11:49 -0500 Subject: Input: Fix button mapping in joydev - BTN_TRIGGER was being mapped twice, resulting in it being the last (instead of first) button on a joystick. Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/joydev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 7d7527f8b02d..627d343dfba1 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -422,7 +422,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct joydev->nkey++; } - for (i = 0; i < BTN_JOYSTICK - BTN_MISC + 1; i++) + for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++) if (test_bit(i + BTN_MISC, dev->keybit)) { joydev->keymap[i] = joydev->nkey; joydev->keypam[joydev->nkey] = i + BTN_MISC; -- cgit v1.2.2 From a07461ec0cffb105c7e7b7404520ea2c74129db0 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 28 May 2005 02:12:00 -0500 Subject: Input: gunze - fix out-of-bound array access reported by Adrian Bunk. Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/gunze.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index c9d0a153671c..53a27e43dd23 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -68,8 +68,7 @@ static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { - gunze->data[10] = 0; - printk(KERN_WARNING "gunze.c: bad packet: >%s<\n", gunze->data); + printk(KERN_WARNING "gunze.c: bad packet: >%.*s<\n", GUNZE_MAX_LENGTH, gunze->data); return; } -- cgit v1.2.2 From 59311de3fb5f293b2e99d7f52e0ab5572759951d Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 28 May 2005 02:12:05 -0500 Subject: Input: automatically disable MUX mode on Toshiba Satellite P10 because it interferes with ALPS touchpad detection and causes horrible death on reboot. Since P10 does not have external PS/2 ports MUX mode does not have any advantages over legacy mode anyway. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index f4c5f7745422..c97ad98171fe 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -88,9 +88,11 @@ static struct dmi_system_id __initdata i8042_dmi_noloop_table[] = { }; /* - * Some Fujitsu notebooks are ahving trouble with touhcpads if + * Some Fujitsu notebooks are having trouble with touchpads if * active multiplexing mode is activated. Luckily they don't have * external PS/2 ports so we can safely disable it. + * ... apparently some Toshibas don't like MUX mode either and + * die horrible death on reboot. */ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { { @@ -121,6 +123,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "FMVLT70H"), }, }, + { + .ident = "Toshiba P10", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P10"), + }, + }, { } }; -- cgit v1.2.2 From b4ff99b60c5e17b1031deb20c9d7688ebe6c9659 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 28 May 2005 02:12:10 -0500 Subject: Input: yet another model that does not play nicely when i8042 is put in MUX mode - Fujitsu Lifebook S6230 Signed-off-by: Dmitry Torokhov --- drivers/input/serio/i8042-x86ia64io.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index c97ad98171fe..0487ecbb8a49 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -116,6 +116,13 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S Series"), }, }, + { + .ident = "Fujitsu Lifebook S6230", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), + DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook S6230"), + }, + }, { .ident = "Fujitsu T70H", .matches = { -- cgit v1.2.2 From 409b7506759430f7c3841d425ca1f8a31eeadece Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 28 May 2005 02:12:18 -0500 Subject: Input: synaptics - reduce verboseness of synaptics driver - there is no reason one driver should take 10 lines in dmesg. Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/synaptics.c | 39 +++++---------------------------------- 1 file changed, 5 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index 69832f8fb720..36c721227b68 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -143,39 +143,6 @@ static int synaptics_identify(struct psmouse *psmouse) return -1; } -static void print_ident(struct synaptics_data *priv) -{ - printk(KERN_INFO "Synaptics Touchpad, model: %ld\n", SYN_ID_MODEL(priv->identity)); - printk(KERN_INFO " Firmware: %ld.%ld\n", SYN_ID_MAJOR(priv->identity), - SYN_ID_MINOR(priv->identity)); - if (SYN_MODEL_ROT180(priv->model_id)) - printk(KERN_INFO " 180 degree mounted touchpad\n"); - if (SYN_MODEL_PORTRAIT(priv->model_id)) - printk(KERN_INFO " portrait touchpad\n"); - printk(KERN_INFO " Sensor: %ld\n", SYN_MODEL_SENSOR(priv->model_id)); - if (SYN_MODEL_NEWABS(priv->model_id)) - printk(KERN_INFO " new absolute packet format\n"); - if (SYN_MODEL_PEN(priv->model_id)) - printk(KERN_INFO " pen detection\n"); - - if (SYN_CAP_EXTENDED(priv->capabilities)) { - printk(KERN_INFO " Touchpad has extended capability bits\n"); - if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap)) - printk(KERN_INFO " -> %d multi-buttons, i.e. besides standard buttons\n", - (int)(SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))); - if (SYN_CAP_MIDDLE_BUTTON(priv->capabilities)) - printk(KERN_INFO " -> middle button\n"); - if (SYN_CAP_FOUR_BUTTON(priv->capabilities)) - printk(KERN_INFO " -> four buttons\n"); - if (SYN_CAP_MULTIFINGER(priv->capabilities)) - printk(KERN_INFO " -> multifinger detection\n"); - if (SYN_CAP_PALMDETECT(priv->capabilities)) - printk(KERN_INFO " -> palm detection\n"); - if (SYN_CAP_PASS_THROUGH(priv->capabilities)) - printk(KERN_INFO " -> pass-through port\n"); - } -} - static int synaptics_query_hardware(struct psmouse *psmouse) { int retries = 0; @@ -666,7 +633,11 @@ int synaptics_init(struct psmouse *psmouse) priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; - print_ident(priv); + printk(KERN_INFO "Synaptics Touchpad, model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx\n", + SYN_ID_MODEL(priv->identity), + SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), + priv->model_id, priv->capabilities, priv->ext_cap); + set_input_params(&psmouse->dev, priv); psmouse->protocol_handler = synaptics_process_byte; -- cgit v1.2.2 From dcefb396c2af4d52fba48dc58b4021794b042046 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sat, 28 May 2005 00:51:24 -0400 Subject: [PATCH] Fix up pwc driver compilation. The neutering of the pwc driver was incomplete. It still references some now-dead files.. Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- drivers/usb/media/pwc/pwc-ctrl.c | 2 -- drivers/usb/media/pwc/pwc-uncompress.c | 2 -- 2 files changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 3e1e4fe20d85..53099190952c 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c @@ -48,8 +48,6 @@ #include "pwc-uncompress.h" #include "pwc-kiara.h" #include "pwc-timon.h" -#include "pwc-dec1.h" -#include "pwc-dec23.h" /* Request types: video */ #define SET_LUM_CTL 0x01 diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c index c596083f06ba..bc3b1635eab0 100644 --- a/drivers/usb/media/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c @@ -29,8 +29,6 @@ #include "pwc.h" #include "pwc-uncompress.h" -#include "pwc-dec1.h" -#include "pwc-dec23.h" int pwc_decompress(struct pwc_device *pdev) { -- cgit v1.2.2 From 9db29258893b08a838e5ecfa4a0933c9c1f2e305 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Fri, 27 May 2005 12:52:58 -0700 Subject: [PATCH] ppc64 iSeries: make virtual DVD-RAMs writable again It appears that another test has been added in the Uniform CDROM layer that must be passed before a DVD-RAM is considered writeable. This patch implements an emulation of the needed packet command for the viocd driver. Signed-off-by: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/cdrom/viocd.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index fcca26c89bbc..38dd9ffbe8bc 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -488,6 +488,20 @@ static int viocd_packet(struct cdrom_device_info *cdi, & (CDC_DVD_RAM | CDC_RAM)) != 0; } break; + case GPCMD_GET_CONFIGURATION: + if (cgc->cmd[3] == CDF_RWRT) { + struct rwrt_feature_desc *rfd = (struct rwrt_feature_desc *)(cgc->buffer + sizeof(struct feature_header)); + + if ((buflen >= + (sizeof(struct feature_header) + sizeof(*rfd))) && + (cdi->ops->capability & ~cdi->mask + & (CDC_DVD_RAM | CDC_RAM))) { + rfd->feature_code = cpu_to_be16(CDF_RWRT); + rfd->curr = 1; + ret = 0; + } + } + break; default: if (cgc->sense) { /* indicate Unknown code */ -- cgit v1.2.2 From b16eeb47292597a8bf3ad53fdaf1f727f57bd8e4 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 27 May 2005 12:53:02 -0700 Subject: [PATCH] ppc32: Fix cpufreq vs. sleep issue Recent kernels occasionally trigger a PMU timeout on some mac laptops, typically on wakeup from sleep. This seem to be caused by either a too big latency caused by the cpufreq switch on wakeup from sleep or by an interrupt beeing lost due to the reset of the interrupt controller done during wakeup. This patch makes that code more robust by stopping PMU auto poll activity around cpufreq changes on machines that use the PMU for such changes (long latency switching involving a CPU hard reset and flush of all caches) and by removing the reset of the open pic interrupt controller on wakeup (that can cause the loss of an interrupt and Darwin doesn't do it, so it must not be necessary). Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/via-pmu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index e654aa5eecd4..bb9f4044c74d 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2421,7 +2421,7 @@ pmac_wakeup_devices(void) /* Re-enable local CPU interrupts */ local_irq_enable(); - mdelay(100); + mdelay(10); preempt_enable(); /* Re-enable clock spreading on some machines */ @@ -2549,7 +2549,9 @@ powerbook_sleep_Core99(void) return ret; } - printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1)); + /* Stop environment and ADB interrupts */ + pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); + pmu_wait_complete(&req); /* Tell PMU what events will wake us up */ pmu_request(&req, NULL, 4, PMU_POWER_EVENTS, PMU_PWR_CLR_WAKEUP_EVENTS, @@ -2611,8 +2613,6 @@ powerbook_sleep_Core99(void) pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); pmu_wait_complete(&req); - printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); - pmac_wakeup_devices(); return 0; -- cgit v1.2.2 From 8bd7f125e2f217c8aa3dff005ae291c81246c340 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 27 May 2005 12:53:03 -0700 Subject: [PATCH] swsusp: ahd_dv_0 can't be stopped This driver wants to set PF_NOFREEZE. Cc: James Bottomley Cc: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/aic7xxx/aic79xx_osm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 550c9921691a..7c02b7dc7098 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -2488,7 +2488,7 @@ ahd_linux_dv_thread(void *data) sprintf(current->comm, "ahd_dv_%d", ahd->unit); #else daemonize("ahd_dv_%d", ahd->unit); - current->flags |= PF_FREEZE; + current->flags |= PF_NOFREEZE; #endif unlock_kernel(); -- cgit v1.2.2 From c1e4c8d3ee3300f363a52fd4cf3d90fdf5098f5a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 27 May 2005 12:53:03 -0700 Subject: [PATCH] fix jumpy mouse cursor on console Do not send empty events to gpm. (Keyboards are assumed to have scroll wheel these days, that makes them part-mouse. That means typing on keyboard generates empty mouse events). From: Dmitry Torokhov Signed-off-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/mousedev.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 564974ce5793..96fb9870834a 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -101,6 +101,7 @@ struct mousedev_list { unsigned char ready, buffer, bufsiz; unsigned char imexseq, impsseq; enum mousedev_emul mode; + unsigned long last_buttons; }; #define MOUSEDEV_SEQ_LEN 6 @@ -224,7 +225,7 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h spin_lock_irqsave(&list->packet_lock, flags); p = &list->packets[list->head]; - if (list->ready && p->buttons != packet->buttons) { + if (list->ready && p->buttons != mousedev->packet.buttons) { unsigned int new_head = (list->head + 1) % PACKET_QUEUE_LEN; if (new_head != list->tail) { p = &list->packets[list->head = new_head]; @@ -249,10 +250,13 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_h p->dz += packet->dz; p->buttons = mousedev->packet.buttons; - list->ready = 1; + if (p->dx || p->dy || p->dz || p->buttons != list->last_buttons) + list->ready = 1; spin_unlock_irqrestore(&list->packet_lock, flags); - kill_fasync(&list->fasync, SIGIO, POLL_IN); + + if (list->ready) + kill_fasync(&list->fasync, SIGIO, POLL_IN); } wake_up_interruptible(&mousedev->wait); @@ -477,9 +481,10 @@ static void mousedev_packet(struct mousedev_list *list, signed char *ps2_data) } if (!p->dx && !p->dy && !p->dz) { - if (list->tail == list->head) + if (list->tail == list->head) { list->ready = 0; - else + list->last_buttons = p->buttons; + } else list->tail = (list->tail + 1) % PACKET_QUEUE_LEN; } -- cgit v1.2.2 From 346e399b2a3a01b323fa74a0937e2d855479833b Mon Sep 17 00:00:00 2001 From: Patrick McManus Date: Sat, 28 May 2005 15:51:46 -0700 Subject: [PATCH] intelfb section fix On Nov 16 2004 a change to intelfbdrv.c was commited (as part of 0.9.2 it looks like) that added __initdata to all of the module param variables that seems to create the opportunity for an oops. I've recently been chasing an OOPS (http://marc.theaimsgroup.com/?l=linux-kernel&m=111552250920370&w=2) I created by reading every file on the /sys file system and I've traced it back to this code in the intelfbdrv. Though I had root privs in my initial problem report, it turns out they are un-necessary to generate the oops - all you've got to do is "cat /sys/module/intelfb/parameters/mode" enough times and eventually it will oops. This is because sysfs automatically exports all module_param declarations to the sysfs file system.. which means those variables can be dynamically evaluated at any later time, which of course means marking them __initdata is a bad idea ;).. when they happen to be char *'s it is an especially bad idea ;). Applying the patch below clears up the OOPS for me. Signed-off-by: Patrick McManus Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/intelfb/intelfbdrv.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 549e22939260..25f9a9a65c24 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c @@ -228,17 +228,17 @@ MODULE_DESCRIPTION( MODULE_LICENSE("Dual BSD/GPL"); MODULE_DEVICE_TABLE(pci, intelfb_pci_table); -static int accel __initdata = 1; -static int vram __initdata = 4; -static int hwcursor __initdata = 1; -static int mtrr __initdata = 1; -static int fixed __initdata = 0; -static int noinit __initdata = 0; -static int noregister __initdata = 0; -static int probeonly __initdata = 0; -static int idonly __initdata = 0; -static int bailearly __initdata = 0; -static char *mode __initdata = NULL; +static int accel = 1; +static int vram = 4; +static int hwcursor = 1; +static int mtrr = 1; +static int fixed = 0; +static int noinit = 0; +static int noregister = 0; +static int probeonly = 0; +static int idonly = 0; +static int bailearly = 0; +static char *mode = NULL; module_param(accel, bool, S_IRUGO); MODULE_PARM_DESC(accel, "Enable console acceleration"); -- cgit v1.2.2 From 5212dd58e67e4b8009107d69a9de45dd2e687496 Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sat, 28 May 2005 15:51:47 -0700 Subject: [PATCH] input: Fix fast scrolling scancodes in atkbd.c Signed-off-by: Vojtech Pavlik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/keyboard/atkbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 79c332f16fc7..af0446c6de82 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -171,9 +171,9 @@ static struct { unsigned char set2; } atkbd_scroll_keys[] = { { ATKBD_SCR_1, 0xc5 }, - { ATKBD_SCR_2, 0xa9 }, - { ATKBD_SCR_4, 0xb6 }, - { ATKBD_SCR_8, 0xa7 }, + { ATKBD_SCR_2, 0x9d }, + { ATKBD_SCR_4, 0xa4 }, + { ATKBD_SCR_8, 0x9b }, { ATKBD_SCR_CLICK, 0xe0 }, { ATKBD_SCR_LEFT, 0xcb }, { ATKBD_SCR_RIGHT, 0xd2 }, -- cgit v1.2.2 From 203fe8b3d1f5b1b527e86f6dbe5b75960acb7f4f Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:48 -0700 Subject: [PATCH] dvb: Fix Mini DiSEqC bug The bug was visible as a warning with gcc-3.4.4 (prerelease) Message: drivers/media/dvb/bt8xx/dst.c:1349: warning: initialization from incompatible pointer type. Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index d047e349d706..2efc6f1caf84 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -915,13 +915,11 @@ static int dst_tone_power_cmd(struct dst_state* state) paket[2] = 0x02; else paket[2] = 0; - if (state->minicmd == SEC_MINI_A) - paket[3] = 0x02; - else - paket[3] = 0; + paket[3] = state->tx_tuna[3]; paket[7] = dst_check_sum (paket, 7); dst_command(state, paket, 8); + return 0; } @@ -1134,6 +1132,29 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) return 0; } +static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) +{ + struct dst_state *state = fe->demodulator_priv; + + if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) + return 0; + + state->minicmd = minicmd; + + switch (minicmd) { + case SEC_MINI_A: + state->tx_tuna[3] = 0x02; + break; + case SEC_MINI_B: + state->tx_tuna[3] = 0xff; + break; + } + dst_tone_power_cmd(state); + + return 0; +} + + static int dst_init(struct dvb_frontend* fe) { struct dst_state* state = (struct dst_state*) fe->demodulator_priv; @@ -1346,7 +1367,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { .read_signal_strength = dst_read_signal_strength, .read_snr = dst_read_snr, - .diseqc_send_burst = dst_set_tone, + .diseqc_send_burst = dst_send_burst, .diseqc_send_master_cmd = dst_set_diseqc, .set_voltage = dst_set_voltage, .set_tone = dst_set_tone, -- cgit v1.2.2 From 0eac3e486e1f246a9d59fee9251cc69e409cb58e Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:50 -0700 Subject: [PATCH] dvb: Remove unnecessary casts Cleanup unnecessary (and undesirable) casts, demodulator_priv is already a void*. Suggestion from Andrew Morton Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 2efc6f1caf84..e5e8c3e869c5 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -978,7 +978,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage); static int dst_write_tuna(struct dvb_frontend* fe) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; int retval; u8 reply; @@ -1046,7 +1046,7 @@ static int dst_write_tuna(struct dvb_frontend* fe) static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; if (state->dst_type == DST_TYPE_IS_TERR) @@ -1064,7 +1064,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { u8 *val; int need_cmd; - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; state->voltage = voltage; @@ -1105,7 +1105,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { u8 *val; - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; state->tone = tone; @@ -1157,7 +1157,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) static int dst_init(struct dvb_frontend* fe) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; static u8 ini_satci_tuna[] = { 9, 0, 3, 0xb6, 1, 0, 0x73, 0x21, 0, 0 }; static u8 ini_satfta_tuna[] = { 0, 0, 3, 0xb6, 1, 0x55, 0xbd, 0x50, 0, 0 }; static u8 ini_tvfta_tuna[] = { 0, 0, 3, 0xb6, 1, 7, 0x0, 0x0, 0, 0 }; @@ -1189,7 +1189,7 @@ static int dst_init(struct dvb_frontend* fe) static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; *status = 0; if (state->diseq_flags & HAS_LOCK) { @@ -1203,7 +1203,7 @@ static int dst_read_status(struct dvb_frontend* fe, fe_status_t* status) static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; dst_get_signal(state); *strength = state->decode_strength; @@ -1213,7 +1213,7 @@ static int dst_read_signal_strength(struct dvb_frontend* fe, u16* strength) static int dst_read_snr(struct dvb_frontend* fe, u16* snr) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; dst_get_signal(state); *snr = state->decode_snr; @@ -1223,7 +1223,7 @@ static int dst_read_snr(struct dvb_frontend* fe, u16* snr) static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; dst_set_freq(state, p->frequency); if (verbose > 4) @@ -1249,7 +1249,7 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; p->frequency = state->decode_freq; p->inversion = state->inversion; @@ -1269,7 +1269,7 @@ static int dst_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet static void dst_release(struct dvb_frontend* fe) { - struct dst_state* state = (struct dst_state*) fe->demodulator_priv; + struct dst_state* state = fe->demodulator_priv; kfree(state); } -- cgit v1.2.2 From 8f6da8f166228c1720d16216a9d82d630c58de57 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:51 -0700 Subject: [PATCH] dvb: Fix LNB power switching Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index e5e8c3e869c5..33cca69d67a7 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -906,10 +906,7 @@ static int dst_tone_power_cmd(struct dst_state* state) if (state->dst_type == DST_TYPE_IS_TERR) return 0; - if (state->voltage == SEC_VOLTAGE_OFF) - paket[4] = 0; - else - paket[4] = 1; + paket[4] = state->tx_tuna[4]; if (state->tone == SEC_TONE_ON) paket[2] = 0x02; @@ -1062,7 +1059,6 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) { - u8 *val; int need_cmd; struct dst_state* state = fe->demodulator_priv; @@ -1072,29 +1068,23 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) return 0; need_cmd = 0; - val = &state->tx_tuna[0]; - val[8] &= ~0x40; switch (voltage) { - case SEC_VOLTAGE_13: - if ((state->diseq_flags & HAS_POWER) == 0) - need_cmd = 1; - state->diseq_flags |= HAS_POWER; - break; + case SEC_VOLTAGE_13: + case SEC_VOLTAGE_18: + if ((state->diseq_flags & HAS_POWER) == 0) + need_cmd = 1; + state->diseq_flags |= HAS_POWER; + state->tx_tuna[4] = 0x01; + break; - case SEC_VOLTAGE_18: - if ((state->diseq_flags & HAS_POWER) == 0) + case SEC_VOLTAGE_OFF: need_cmd = 1; - state->diseq_flags |= HAS_POWER; - val[8] |= 0x40; - break; - - case SEC_VOLTAGE_OFF: - need_cmd = 1; - state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); - break; + state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); + state->tx_tuna[4] = 0x00; + break; - default: - return -EINVAL; + default: + return -EINVAL; } if (need_cmd) dst_tone_power_cmd(state); -- cgit v1.2.2 From 86360a3edeb6b7b6230dc13ef6835d2851409502 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:51 -0700 Subject: [PATCH] dvb: Fix 22k tone control Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 33cca69d67a7..8104240a2208 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -907,12 +907,7 @@ static int dst_tone_power_cmd(struct dst_state* state) return 0; paket[4] = state->tx_tuna[4]; - - if (state->tone == SEC_TONE_ON) - paket[2] = 0x02; - else - paket[2] = 0; - + paket[2] = state->tx_tuna[2]; paket[3] = state->tx_tuna[3]; paket[7] = dst_check_sum (paket, 7); dst_command(state, paket, 8); @@ -1094,7 +1089,6 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) { - u8 *val; struct dst_state* state = fe->demodulator_priv; state->tone = tone; @@ -1102,20 +1096,17 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) if (state->dst_type == DST_TYPE_IS_TERR) return 0; - val = &state->tx_tuna[0]; - - val[8] &= ~0x1; - switch (tone) { - case SEC_TONE_OFF: - break; + case SEC_TONE_OFF: + state->tx_tuna[2] = 0xff; + break; - case SEC_TONE_ON: - val[8] |= 1; - break; + case SEC_TONE_ON: + state->tx_tuna[2] = 0x02; + break; - default: - return -EINVAL; + default: + return -EINVAL; } dst_tone_power_cmd(state); -- cgit v1.2.2 From 226d97ec3e47b54ecc13f6ea3c300dc6a1b290c3 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Sat, 28 May 2005 15:51:52 -0700 Subject: [PATCH] dvb: Small cleanup Miscellaneous cleanup Signed-off-by: Manu Abraham Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/dvb/bt8xx/dst.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index 8104240a2208..1339912c308b 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c @@ -1041,7 +1041,7 @@ static int dst_set_diseqc(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* struct dst_state* state = fe->demodulator_priv; u8 paket[8] = { 0x00, 0x08, 0x04, 0xe0, 0x10, 0x38, 0xf0, 0xec }; - if (state->dst_type == DST_TYPE_IS_TERR) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; if (cmd->msg_len == 0 || cmd->msg_len > 4) @@ -1059,7 +1059,7 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) state->voltage = voltage; - if (state->dst_type == DST_TYPE_IS_TERR) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; need_cmd = 0; @@ -1093,7 +1093,7 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) state->tone = tone; - if (state->dst_type == DST_TYPE_IS_TERR) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; switch (tone) { @@ -1117,7 +1117,7 @@ static int dst_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t minicmd) { struct dst_state *state = fe->demodulator_priv; - if ((state->dst_type == DST_TYPE_IS_TERR) || (state->dst_type == DST_TYPE_IS_CABLE)) + if (state->dst_type != DST_TYPE_IS_SAT) return 0; state->minicmd = minicmd; -- cgit v1.2.2 From 7d6064d44bc79e328f2794ee7322ba2676511e2b Mon Sep 17 00:00:00 2001 From: Vojtech Pavlik Date: Sun, 29 May 2005 01:27:44 -0500 Subject: Input: Fix fast scrolling scancodes in atkbd.c Signed-off-by: Vojtech Pavlik Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/atkbd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 79c332f16fc7..af0446c6de82 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -171,9 +171,9 @@ static struct { unsigned char set2; } atkbd_scroll_keys[] = { { ATKBD_SCR_1, 0xc5 }, - { ATKBD_SCR_2, 0xa9 }, - { ATKBD_SCR_4, 0xb6 }, - { ATKBD_SCR_8, 0xa7 }, + { ATKBD_SCR_2, 0x9d }, + { ATKBD_SCR_4, 0xa4 }, + { ATKBD_SCR_8, 0x9b }, { ATKBD_SCR_CLICK, 0xe0 }, { ATKBD_SCR_LEFT, 0xcb }, { ATKBD_SCR_RIGHT, 0xd2 }, -- cgit v1.2.2 From 7238cfb3342078ad6d1dd06c7b567da428672476 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 29 May 2005 14:48:20 -0400 Subject: libata: bump version --- drivers/scsi/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index 6518226b8f87..d90430bbb0de 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h @@ -26,7 +26,7 @@ #define __LIBATA_H__ #define DRV_NAME "libata" -#define DRV_VERSION "1.10" /* must be exactly four chars */ +#define DRV_VERSION "1.11" /* must be exactly four chars */ struct ata_scsi_args { u16 *id; -- cgit v1.2.2 From 4cafd3f533475c976879d85773735c004f09f576 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:56:34 -0700 Subject: [TG3]: Add basic selftest infrastructure Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f10dd74988c4..088ed9f634e5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -133,6 +133,8 @@ /* number of ETHTOOL_GSTATS u64's */ #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) +#define TG3_NUM_TEST 6 + static char version[] __devinitdata = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; @@ -316,6 +318,17 @@ static struct { { "nic_tx_threshold_hit" } }; +static struct { + const char string[ETH_GSTRING_LEN]; +} ethtool_test_keys[TG3_NUM_TEST] = { + { "nvram test (online) " }, + { "link test (online) " }, + { "register test (offline)" }, + { "memory test (offline)" }, + { "loopback test (offline)" }, + { "interrupt test (offline)" }, +}; + static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) { if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { @@ -7199,12 +7212,20 @@ static int tg3_get_stats_count (struct net_device *dev) return TG3_NUM_STATS; } +static int tg3_get_test_count (struct net_device *dev) +{ + return TG3_NUM_TEST; +} + static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) { switch (stringset) { case ETH_SS_STATS: memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); break; + case ETH_SS_TEST: + memcpy(buf, ðtool_test_keys, sizeof(ethtool_test_keys)); + break; default: WARN_ON(1); /* we need a WARN() */ break; @@ -7218,6 +7239,11 @@ static void tg3_get_ethtool_stats (struct net_device *dev, memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); } +static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, + u64 *data) +{ +} + static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *data = if_mii(ifr); @@ -7331,6 +7357,8 @@ static struct ethtool_ops tg3_ethtool_ops = { .get_tso = ethtool_op_get_tso, .set_tso = tg3_set_tso, #endif + .self_test_count = tg3_get_test_count, + .self_test = tg3_self_test, .get_strings = tg3_get_strings, .get_stats_count = tg3_get_stats_count, .get_ethtool_stats = tg3_get_ethtool_stats, -- cgit v1.2.2 From 566f86adb336637d03900f53b886d879aa5f5d56 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:56:58 -0700 Subject: [TG3]: Add nvram test Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 088ed9f634e5..ab2fa213b301 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7239,9 +7239,59 @@ static void tg3_get_ethtool_stats (struct net_device *dev, memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); } +#define NVRAM_TEST_SIZE 0x100 + +static int tg3_test_nvram(struct tg3 *tp) +{ + u32 *buf, csum; + int i, j, err = 0; + + buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { + u32 val; + + if ((err = tg3_nvram_read(tp, i, &val)) != 0) + break; + buf[j] = cpu_to_le32(val); + } + if (i < NVRAM_TEST_SIZE) + goto out; + + err = -EIO; + if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) + goto out; + + /* Bootstrap checksum at offset 0x10 */ + csum = calc_crc((unsigned char *) buf, 0x10); + if(csum != cpu_to_le32(buf[0x10/4])) + goto out; + + /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ + csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); + if (csum != cpu_to_le32(buf[0xfc/4])) + goto out; + + err = 0; + +out: + kfree(buf); + return err; +} + static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *data) { + struct tg3 *tp = netdev_priv(dev); + + memset(data, 0, sizeof(u64) * TG3_NUM_TEST); + + if (tg3_test_nvram(tp) != 0) { + etest->flags |= ETH_TEST_FL_FAILED; + data[0] = 1; + } } static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -- cgit v1.2.2 From ca43007a92662621e5819912fc31c346e3a2eed8 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:57:23 -0700 Subject: [TG3]: Add link test Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ab2fa213b301..30349c5fd73c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7281,6 +7281,32 @@ out: return err; } +#define TG3_SERDES_TIMEOUT_SEC 2 +#define TG3_COPPER_TIMEOUT_SEC 6 + +static int tg3_test_link(struct tg3 *tp) +{ + int i, max; + + if (!netif_running(tp->dev)) + return -ENODEV; + + if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) + max = TG3_SERDES_TIMEOUT_SEC; + else + max = TG3_COPPER_TIMEOUT_SEC; + + for (i = 0; i < max; i++) { + if (netif_carrier_ok(tp->dev)) + return 0; + + if (msleep_interruptible(1000)) + break; + } + + return -EIO; +} + static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *data) { @@ -7292,6 +7318,10 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, etest->flags |= ETH_TEST_FL_FAILED; data[0] = 1; } + if (tg3_test_link(tp) != 0) { + etest->flags |= ETH_TEST_FL_FAILED; + data[1] = 1; + } } static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -- cgit v1.2.2 From 944d980ecaabe44616a9e2d50101ce774f517bb6 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:57:48 -0700 Subject: [TG3]: Add parameter to tg3_halt Add a reset kind parameter to tg3_halt() so that the RESET_KIND_SUSPEND parameter can be passed to tg3_halt() before doing offline tests. All other calls to tg3_halt() will use the RESET_KIND_SHUTDOWN parameter. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 30349c5fd73c..73f6e962ed5e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -3083,7 +3083,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, } static int tg3_init_hw(struct tg3 *); -static int tg3_halt(struct tg3 *, int); +static int tg3_halt(struct tg3 *, int, int); #ifdef CONFIG_NET_POLL_CONTROLLER static void tg3_poll_controller(struct net_device *dev) @@ -3107,7 +3107,7 @@ static void tg3_reset_task(void *_data) restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; - tg3_halt(tp, 0); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); tg3_init_hw(tp); tg3_netif_start(tp); @@ -3453,7 +3453,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_set_mtu(dev, tp, new_mtu); @@ -4144,19 +4144,19 @@ static void tg3_stop_fw(struct tg3 *tp) } /* tp->lock is held. */ -static int tg3_halt(struct tg3 *tp, int silent) +static int tg3_halt(struct tg3 *tp, int kind, int silent) { int err; tg3_stop_fw(tp); - tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); + tg3_write_sig_pre_reset(tp, kind); tg3_abort_hw(tp, silent); err = tg3_chip_reset(tp); - tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); - tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); + tg3_write_sig_legacy(tp, kind); + tg3_write_sig_post_reset(tp, kind); if (err) return err; @@ -5997,7 +5997,7 @@ static int tg3_test_msi(struct tg3 *tp) spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); err = tg3_init_hw(tp); spin_unlock(&tp->tx_lock); @@ -6073,7 +6073,7 @@ static int tg3_open(struct net_device *dev) err = tg3_init_hw(tp); if (err) { - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); } else { if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) @@ -6117,7 +6117,7 @@ static int tg3_open(struct net_device *dev) pci_disable_msi(tp->pdev); tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; } - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); tg3_free_consistent(tp); @@ -6390,7 +6390,7 @@ static int tg3_close(struct net_device *dev) tg3_disable_ints(tp); - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_free_rings(tp); tp->tg3_flags &= ~(TG3_FLAG_INIT_COMPLETE | @@ -7110,7 +7110,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e tp->tx_pending = ering->tx_pending; if (netif_running(dev)) { - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_init_hw(tp); tg3_netif_start(tp); } @@ -7153,7 +7153,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; if (netif_running(dev)) { - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); tg3_init_hw(tp); tg3_netif_start(tp); } @@ -9586,7 +9586,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { pci_save_state(tp->pdev); tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); } err = tg3_test_dma(tp); @@ -9713,7 +9713,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) spin_lock_irq(&tp->lock); spin_lock(&tp->tx_lock); - tg3_halt(tp, 1); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); spin_unlock(&tp->tx_lock); spin_unlock_irq(&tp->lock); -- cgit v1.2.2 From a71116d1f3b85a69fe3a3acec9223fefb4b1fc66 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:58:11 -0700 Subject: [TG3]: Add register test Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 73f6e962ed5e..4589f8f90119 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7307,6 +7307,219 @@ static int tg3_test_link(struct tg3 *tp) return -EIO; } +/* Only test the commonly used registers */ +static int tg3_test_registers(struct tg3 *tp) +{ + int i, is_5705; + u32 offset, read_mask, write_mask, val, save_val, read_val; + static struct { + u16 offset; + u16 flags; +#define TG3_FL_5705 0x1 +#define TG3_FL_NOT_5705 0x2 +#define TG3_FL_NOT_5788 0x4 + u32 read_mask; + u32 write_mask; + } reg_tbl[] = { + /* MAC Control Registers */ + { MAC_MODE, TG3_FL_NOT_5705, + 0x00000000, 0x00ef6f8c }, + { MAC_MODE, TG3_FL_5705, + 0x00000000, 0x01ef6b8c }, + { MAC_STATUS, TG3_FL_NOT_5705, + 0x03800107, 0x00000000 }, + { MAC_STATUS, TG3_FL_5705, + 0x03800100, 0x00000000 }, + { MAC_ADDR_0_HIGH, 0x0000, + 0x00000000, 0x0000ffff }, + { MAC_ADDR_0_LOW, 0x0000, + 0x00000000, 0xffffffff }, + { MAC_RX_MTU_SIZE, 0x0000, + 0x00000000, 0x0000ffff }, + { MAC_TX_MODE, 0x0000, + 0x00000000, 0x00000070 }, + { MAC_TX_LENGTHS, 0x0000, + 0x00000000, 0x00003fff }, + { MAC_RX_MODE, TG3_FL_NOT_5705, + 0x00000000, 0x000007fc }, + { MAC_RX_MODE, TG3_FL_5705, + 0x00000000, 0x000007dc }, + { MAC_HASH_REG_0, 0x0000, + 0x00000000, 0xffffffff }, + { MAC_HASH_REG_1, 0x0000, + 0x00000000, 0xffffffff }, + { MAC_HASH_REG_2, 0x0000, + 0x00000000, 0xffffffff }, + { MAC_HASH_REG_3, 0x0000, + 0x00000000, 0xffffffff }, + + /* Receive Data and Receive BD Initiator Control Registers. */ + { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, + 0x00000000, 0x00000003 }, + { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { RCVDBDI_STD_BD+0, 0x0000, + 0x00000000, 0xffffffff }, + { RCVDBDI_STD_BD+4, 0x0000, + 0x00000000, 0xffffffff }, + { RCVDBDI_STD_BD+8, 0x0000, + 0x00000000, 0xffff0002 }, + { RCVDBDI_STD_BD+0xc, 0x0000, + 0x00000000, 0xffffffff }, + + /* Receive BD Initiator Control Registers. */ + { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { RCVBDI_STD_THRESH, TG3_FL_5705, + 0x00000000, 0x000003ff }, + { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + + /* Host Coalescing Control Registers. */ + { HOSTCC_MODE, TG3_FL_NOT_5705, + 0x00000000, 0x00000004 }, + { HOSTCC_MODE, TG3_FL_5705, + 0x00000000, 0x000000f6 }, + { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_RXCOL_TICKS, TG3_FL_5705, + 0x00000000, 0x000003ff }, + { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_TXCOL_TICKS, TG3_FL_5705, + 0x00000000, 0x000003ff }, + { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, + 0x00000000, 0x000000ff }, + { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, + 0x00000000, 0x000000ff }, + { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, + 0x00000000, 0x000000ff }, + { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, + 0x00000000, 0x000000ff }, + { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, + 0x00000000, 0xffffffff }, + { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, + 0x00000000, 0xffffffff }, + { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, + 0x00000000, 0xffffffff }, + { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, + 0xffffffff, 0x00000000 }, + { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, + 0xffffffff, 0x00000000 }, + + /* Buffer Manager Control Registers. */ + { BUFMGR_MB_POOL_ADDR, 0x0000, + 0x00000000, 0x007fff80 }, + { BUFMGR_MB_POOL_SIZE, 0x0000, + 0x00000000, 0x007fffff }, + { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, + 0x00000000, 0x0000003f }, + { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, + 0x00000000, 0x000001ff }, + { BUFMGR_MB_HIGH_WATER, 0x0000, + 0x00000000, 0x000001ff }, + { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, + 0xffffffff, 0x00000000 }, + { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, + 0xffffffff, 0x00000000 }, + + /* Mailbox Registers */ + { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, + 0x00000000, 0x000001ff }, + { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, + 0x00000000, 0x000001ff }, + { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, + 0x00000000, 0x000007ff }, + { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, + 0x00000000, 0x000001ff }, + + { 0xffff, 0x0000, 0x00000000, 0x00000000 }, + }; + + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + is_5705 = 1; + else + is_5705 = 0; + + for (i = 0; reg_tbl[i].offset != 0xffff; i++) { + if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) + continue; + + if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) + continue; + + if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) && + (reg_tbl[i].flags & TG3_FL_NOT_5788)) + continue; + + offset = (u32) reg_tbl[i].offset; + read_mask = reg_tbl[i].read_mask; + write_mask = reg_tbl[i].write_mask; + + /* Save the original register content */ + save_val = tr32(offset); + + /* Determine the read-only value. */ + read_val = save_val & read_mask; + + /* Write zero to the register, then make sure the read-only bits + * are not changed and the read/write bits are all zeros. + */ + tw32(offset, 0); + + val = tr32(offset); + + /* Test the read-only and read/write bits. */ + if (((val & read_mask) != read_val) || (val & write_mask)) + goto out; + + /* Write ones to all the bits defined by RdMask and WrMask, then + * make sure the read-only bits are not changed and the + * read/write bits are all ones. + */ + tw32(offset, read_mask | write_mask); + + val = tr32(offset); + + /* Test the read-only bits. */ + if ((val & read_mask) != read_val) + goto out; + + /* Test the read/write bits. */ + if ((val & write_mask) != write_mask) + goto out; + + tw32(offset, save_val); + } + + return 0; + +out: + printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); + tw32(offset, save_val); + return -EIO; +} + static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *data) { @@ -7322,6 +7535,34 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, etest->flags |= ETH_TEST_FL_FAILED; data[1] = 1; } + if (etest->flags & ETH_TEST_FL_OFFLINE) { + if (netif_running(dev)) + tg3_netif_stop(tp); + + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + + tg3_halt(tp, RESET_KIND_SUSPEND, 1); + tg3_nvram_lock(tp); + tg3_halt_cpu(tp, RX_CPU_BASE); + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) + tg3_halt_cpu(tp, TX_CPU_BASE); + tg3_nvram_unlock(tp); + + if (tg3_test_registers(tp) != 0) { + etest->flags |= ETH_TEST_FL_FAILED; + data[2] = 1; + } + + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); + if (netif_running(dev)) { + tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; + tg3_init_hw(tp); + tg3_netif_start(tp); + } + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + } } static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -- cgit v1.2.2 From 7942e1dbd7252b480ed238096dca617189d293df Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:58:36 -0700 Subject: [TG3]: Add memory test Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 4589f8f90119..49cb7b3e2835 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7520,6 +7520,62 @@ out: return -EIO; } +static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) +{ + static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; + int i; + u32 j; + + for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) { + for (j = 0; j < len; j += 4) { + u32 val; + + tg3_write_mem(tp, offset + j, test_pattern[i]); + tg3_read_mem(tp, offset + j, &val); + if (val != test_pattern[i]) + return -EIO; + } + } + return 0; +} + +static int tg3_test_memory(struct tg3 *tp) +{ + static struct mem_entry { + u32 offset; + u32 len; + } mem_tbl_570x[] = { + { 0x00000000, 0x01000}, + { 0x00002000, 0x1c000}, + { 0xffffffff, 0x00000} + }, mem_tbl_5705[] = { + { 0x00000100, 0x0000c}, + { 0x00000200, 0x00008}, + { 0x00000b50, 0x00400}, + { 0x00004000, 0x00800}, + { 0x00006000, 0x01000}, + { 0x00008000, 0x02000}, + { 0x00010000, 0x0e000}, + { 0xffffffff, 0x00000} + }; + struct mem_entry *mem_tbl; + int err = 0; + int i; + + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) + mem_tbl = mem_tbl_5705; + else + mem_tbl = mem_tbl_570x; + + for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { + if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset, + mem_tbl[i].len)) != 0) + break; + } + + return err; +} + static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *data) { @@ -7553,6 +7609,10 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, etest->flags |= ETH_TEST_FL_FAILED; data[2] = 1; } + if (tg3_test_memory(tp) != 0) { + etest->flags |= ETH_TEST_FL_FAILED; + data[3] = 1; + } tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); if (netif_running(dev)) { -- cgit v1.2.2 From c76949a6826fc11efcd6bb1abdca1ae02761071d Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:58:59 -0700 Subject: [TG3]: Add loopback test The test will loopback one packet in MAC loopback mode and verify the packet data. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 49cb7b3e2835..2a771fd4c7cd 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7576,6 +7576,117 @@ static int tg3_test_memory(struct tg3 *tp) return err; } +static int tg3_test_loopback(struct tg3 *tp) +{ + u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; + u32 desc_idx; + struct sk_buff *skb, *rx_skb; + u8 *tx_data; + dma_addr_t map; + int num_pkts, tx_len, rx_len, i, err; + struct tg3_rx_buffer_desc *desc; + + if (!netif_running(tp->dev)) + return -ENODEV; + + err = -EIO; + + tg3_abort_hw(tp, 1); + + /* Clearing this flag to keep interrupts disabled */ + tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; + tg3_reset_hw(tp); + + mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | + MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | + MAC_MODE_PORT_MODE_GMII; + tw32(MAC_MODE, mac_mode); + + tx_len = 1514; + skb = dev_alloc_skb(tx_len); + tx_data = skb_put(skb, tx_len); + memcpy(tx_data, tp->dev->dev_addr, 6); + memset(tx_data + 6, 0x0, 8); + + tw32(MAC_RX_MTU_SIZE, tx_len + 4); + + for (i = 14; i < tx_len; i++) + tx_data[i] = (u8) (i & 0xff); + + map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE); + + tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | + HOSTCC_MODE_NOW); + + udelay(10); + + rx_start_idx = tp->hw_status->idx[0].rx_producer; + + send_idx = 0; + num_pkts = 0; + + tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); + + send_idx++; + num_pkts++; + + tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); + tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); + + udelay(10); + + for (i = 0; i < 10; i++) { + tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | + HOSTCC_MODE_NOW); + + udelay(10); + + tx_idx = tp->hw_status->idx[0].tx_consumer; + rx_idx = tp->hw_status->idx[0].rx_producer; + if ((tx_idx == send_idx) && + (rx_idx == (rx_start_idx + num_pkts))) + break; + } + + pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); + dev_kfree_skb(skb); + + if (tx_idx != send_idx) + goto out; + + if (rx_idx != rx_start_idx + num_pkts) + goto out; + + desc = &tp->rx_rcb[rx_start_idx]; + desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; + opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; + if (opaque_key != RXD_OPAQUE_RING_STD) + goto out; + + if ((desc->err_vlan & RXD_ERR_MASK) != 0 && + (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) + goto out; + + rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; + if (rx_len != tx_len) + goto out; + + rx_skb = tp->rx_std_buffers[desc_idx].skb; + + map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping); + pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE); + + for (i = 14; i < tx_len; i++) { + if (*(rx_skb->data + i) != (u8) (i & 0xff)) + goto out; + } + err = 0; + + /* tg3_free_rings will unmap and free the rx_skb */ +out: + return err; +} + static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, u64 *data) { @@ -7613,6 +7724,10 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, etest->flags |= ETH_TEST_FL_FAILED; data[3] = 1; } + if (tg3_test_loopback(tp) != 0) { + etest->flags |= ETH_TEST_FL_FAILED; + data[4] = 1; + } tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); if (netif_running(dev)) { -- cgit v1.2.2 From d4bc3927d284784b3f0bff05b4eed2242cc3e226 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:59:20 -0700 Subject: [TG3]: Add interrupt test This test uses the previously added tg3_test_interrupt() to perform the test. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 2a771fd4c7cd..82afd26a829f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5894,6 +5894,9 @@ static int tg3_test_interrupt(struct tg3 *tp) int err, i; u32 int_mbox = 0; + if (!netif_running(dev)) + return -ENODEV; + tg3_disable_ints(tp); free_irq(tp->pdev->irq, dev); @@ -7729,6 +7732,15 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, data[4] = 1; } + spin_unlock(&tp->tx_lock); + spin_unlock_irq(&tp->lock); + if (tg3_test_interrupt(tp) != 0) { + etest->flags |= ETH_TEST_FL_FAILED; + data[5] = 1; + } + spin_lock_irq(&tp->lock); + spin_lock(&tp->tx_lock); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); if (netif_running(dev)) { tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; -- cgit v1.2.2 From 1b62815193f6c20c60958e5347751155833e3d35 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 29 May 2005 14:59:49 -0700 Subject: [TG3]: Fix bug in tg3_load_firmware_cpu Add tg3_nvram_lock() and tg3_nvram_unlock() calls around tg3_halt_cpu(). It is possible that the bootcode may be loading code from nvram during this call and stopping the cpu without getting the lock may cause uncompleted nvram data to be left in the nvram data register. Subsequent calls to read/write nvram data will fail. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 82afd26a829f..fc9b5cd957aa 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -4370,7 +4370,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b */ tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; + /* It is possible that bootcode is still loading at this point. + * Get the nvram lock first before halting the cpu. + */ + tg3_nvram_lock(tp); err = tg3_halt_cpu(tp, cpu_base); + tg3_nvram_unlock(tp); if (err) goto out; -- cgit v1.2.2 From 4e7c6816d680d1945916db047a47847afe4b9b02 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 31 May 2005 17:47:36 +0200 Subject: [PATCH] Relax idecd dma alignment check Only the address needs alignment of mask bits, length should work with a relaxed alignment check. Signed-off-by: Jens Axboe [ This is take 2: make the length check be for 16-byte alignment, not just word alignment. That should hopefully keep everybody happy, while still allowing CD writing with DMA ] Signed-off-by: Linus Torvalds --- drivers/ide/ide-cd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 78e3e7b24d7d..39f3e9101ed4 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1936,7 +1936,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) * NOTE! The "len" and "addr" checks should possibly have * separate masks. */ - if ((rq->data_len & mask) || (addr & mask)) + if ((rq->data_len & 15) || (addr & mask)) info->dma = 0; } -- cgit v1.2.2 From 4a4e5787e0b721021fe0a456ddc987a04cebfc8d Mon Sep 17 00:00:00 2001 From: "R.Marek@sh.cvut.cz" Date: Thu, 21 Apr 2005 09:07:56 +0000 Subject: [PATCH] I2C: ALI1563 SMBus driver fix This patch fixes "grave" bugs in i2c-ali1563 driver. It seems on recent chipset revisions the HSTS_DONE is set only for block transfers, so we must detect the end of ordinary transaction other way. Also due to missing and mask, setting other transfer modes was not possible. Moreover the continous byte mode transfer uses DAT0 for command rather than CMD command. All those changes were tested with help of Chunhao Huang from Winbond. I'm willing to maintain the driver. Second patch adds me as maintainer if this is neccessary. Signed-Off-By: Rudolf Marek Signed-off-by: Greg Kroah-Hartman --- drivers/i2c/busses/i2c-ali1563.c | 46 +++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index 35710818fe47..fdd881aee618 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c @@ -2,6 +2,7 @@ * i2c-ali1563.c - i2c driver for the ALi 1563 Southbridge * * Copyright (C) 2004 Patrick Mochel + * 2005 Rudolf Marek * * The 1563 southbridge is deceptively similar to the 1533, with a * few notable exceptions. One of those happens to be the fact they @@ -57,10 +58,11 @@ #define HST_CNTL2_BLOCK 0x05 +#define HST_CNTL2_SIZEMASK 0x38 static unsigned short ali1563_smba; -static int ali1563_transaction(struct i2c_adapter * a) +static int ali1563_transaction(struct i2c_adapter * a, int size) { u32 data; int timeout; @@ -73,7 +75,7 @@ static int ali1563_transaction(struct i2c_adapter * a) data = inb_p(SMB_HST_STS); if (data & HST_STS_BAD) { - dev_warn(&a->dev,"ali1563: Trying to reset busy device\n"); + dev_err(&a->dev, "ali1563: Trying to reset busy device\n"); outb_p(data | HST_STS_BAD,SMB_HST_STS); data = inb_p(SMB_HST_STS); if (data & HST_STS_BAD) @@ -94,19 +96,31 @@ static int ali1563_transaction(struct i2c_adapter * a) if (timeout && !(data & HST_STS_BAD)) return 0; - dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", - timeout ? "Timeout " : "", - data & HST_STS_FAIL ? "Transaction Failed " : "", - data & HST_STS_BUSERR ? "No response or Bus Collision " : "", - data & HST_STS_DEVERR ? "Device Error " : "", - !(data & HST_STS_DONE) ? "Transaction Never Finished " : ""); - if (!(data & HST_STS_DONE)) + if (!timeout) { + dev_err(&a->dev, "Timeout - Trying to KILL transaction!\n"); /* Issue 'kill' to host controller */ outb_p(HST_CNTL2_KILL,SMB_HST_CNTL2); - else - /* Issue timeout to reset all devices on bus */ + data = inb_p(SMB_HST_STS); + } + + /* device error - no response, ignore the autodetection case */ + if ((data & HST_STS_DEVERR) && (size != HST_CNTL2_QUICK)) { + dev_err(&a->dev, "Device error!\n"); + } + + /* bus collision */ + if (data & HST_STS_BUSERR) { + dev_err(&a->dev, "Bus collision!\n"); + /* Issue timeout, hoping it helps */ outb_p(HST_CNTL1_TIMEOUT,SMB_HST_CNTL1); + } + + if (data & HST_STS_FAIL) { + dev_err(&a->dev, "Cleaning fail after KILL!\n"); + outb_p(0x0,SMB_HST_CNTL2); + } + return -1; } @@ -149,7 +163,7 @@ static int ali1563_block_start(struct i2c_adapter * a) if (timeout && !(data & HST_STS_BAD)) return 0; - dev_warn(&a->dev, "SMBus Error: %s%s%s%s%s\n", + dev_err(&a->dev, "SMBus Error: %s%s%s%s%s\n", timeout ? "Timeout " : "", data & HST_STS_FAIL ? "Transaction Failed " : "", data & HST_STS_BUSERR ? "No response or Bus Collision " : "", @@ -242,13 +256,15 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, } outb_p(((addr & 0x7f) << 1) | (rw & 0x01), SMB_HST_ADD); - outb_p(inb_p(SMB_HST_CNTL2) | (size << 3), SMB_HST_CNTL2); + outb_p((inb_p(SMB_HST_CNTL2) & ~HST_CNTL2_SIZEMASK) | (size << 3), SMB_HST_CNTL2); /* Write the command register */ + switch(size) { case HST_CNTL2_BYTE: if (rw== I2C_SMBUS_WRITE) - outb_p(cmd, SMB_HST_CMD); + /* Beware it uses DAT0 register and not CMD! */ + outb_p(cmd, SMB_HST_DAT0); break; case HST_CNTL2_BYTE_DATA: outb_p(cmd, SMB_HST_CMD); @@ -268,7 +284,7 @@ static s32 ali1563_access(struct i2c_adapter * a, u16 addr, goto Done; } - if ((error = ali1563_transaction(a))) + if ((error = ali1563_transaction(a, size))) goto Done; if ((rw == I2C_SMBUS_WRITE) || (size == HST_CNTL2_QUICK)) -- cgit v1.2.2 From 1e9a47b62f7daf5a94fdd74a94dd4e076f44909a Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 26 May 2005 05:55:55 -0700 Subject: [PATCH] USB: sl811-hcd fixes Various fixes to the sl811-hcd driver: * Fix small glitches that crept in during recent evolution of usbcore's hcd glue layer, coupling endpoint state records to usbcore and active urbs. (As noted by folk whose boards weren't stuck on 2.6.9 kernels...) * Cope with various system-specific issues: - Some configurations (e.g. a CF-card uses this chip) have iospace addresses for the two registers, rather than memory mapped ones. - Some configurations do interesting things with IRQs; maybe the line is shared, or it doesn't support level triggering. - Not all boards can drive the chip reset line in software. * Address a potential race during unlinking. * Tweak probe/remove section info to handle the case where this segment of a platform bus is hotpluggable (e.g. CF card). (The basic problem is that CONFIG_HOTPLUG is global, which is wrong since not all busses can hotplug even on hotplug-friendly systems...) Also export the driver, so that the CF driver can depend on it. Also removed some annoying end-of-line whitespace. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/sl811-hcd.c | 146 ++++++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a374b7692073..99d43f758ad0 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -2,8 +2,8 @@ * SL811HS HCD (Host Controller Driver) for USB. * * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) - * Copyright (C) 2004 David Brownell - * + * Copyright (C) 2004-2005 David Brownell + * * Periodic scheduling is based on Roman's OHCI code * Copyright (C) 1999 Roman Weissgaerber * @@ -15,7 +15,7 @@ * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" * document (providing significant pieces missing from that spec); plus * the SL811S spec if you want peripheral side info. - */ + */ /* * Status: Passed basic stress testing, works with hubs, mice, keyboards, @@ -67,7 +67,7 @@ MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION "15 Dec 2004" +#define DRIVER_VERSION "19 May 2005" #ifndef DEBUG @@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on) /* reset as thoroughly as we can */ if (sl811->board && sl811->board->reset) sl811->board->reset(hcd->self.controller); + else { + sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); + mdelay(20); + } sl811_write(sl811, SL11H_IRQ_ENABLE, 0); sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); @@ -443,6 +447,7 @@ static void finish_request( spin_lock(&urb->lock); if (urb->status == -EINPROGRESS) urb->status = status; + urb->hcpriv = NULL; spin_unlock(&urb->lock); spin_unlock(&sl811->lock); @@ -472,7 +477,7 @@ static void finish_request( if (*prev) *prev = ep->next; sl811->load[i] -= ep->load; - } + } ep->branch = PERIODIC_SIZE; sl811->periodic_count--; sl811_to_hcd(sl811)->self.bandwidth_allocated @@ -661,9 +666,9 @@ retry: #ifdef QUIRK2 /* this may no longer be necessary ... */ - if (irqstat == 0 && ret == IRQ_NONE) { + if (irqstat == 0) { irqstat = checkdone(sl811); - if (irqstat /* && irq != ~0 */ ) + if (irqstat) sl811->stat_lost++; } #endif @@ -722,7 +727,8 @@ retry: if (sl811->active_a) { sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); finish_request(sl811, sl811->active_a, - container_of(sl811->active_a->hep->urb_list.next, + container_of(sl811->active_a + ->hep->urb_list.next, struct urb, urb_list), NULL, -ESHUTDOWN); sl811->active_a = NULL; @@ -731,7 +737,8 @@ retry: if (sl811->active_b) { sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); finish_request(sl811, sl811->active_b, - container_of(sl811->active_b->hep->urb_list.next, + container_of(sl811->active_b + ->hep->urb_list.next, struct urb, urb_list), NULL, -ESHUTDOWN); sl811->active_b = NULL; @@ -761,7 +768,7 @@ retry: goto retry; } - if (sl811->periodic_count == 0 && list_empty(&sl811->async)) + if (sl811->periodic_count == 0 && list_empty(&sl811->async)) sofirq_off(sl811); sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); @@ -796,7 +803,7 @@ static int balance(struct sl811 *sl811, u16 period, u16 load) } if (j < PERIODIC_SIZE) continue; - branch = i; + branch = i; } } return branch; @@ -890,6 +897,7 @@ static int sl811h_urb_enqueue( break; } + ep->hep = hep; hep->hcpriv = ep; } @@ -961,15 +969,16 @@ fail: static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) { struct sl811 *sl811 = hcd_to_sl811(hcd); - struct usb_host_endpoint *hep = urb->hcpriv; + struct usb_host_endpoint *hep; unsigned long flags; struct sl811h_ep *ep; int retval = 0; + spin_lock_irqsave(&sl811->lock, flags); + hep = urb->hcpriv; if (!hep) - return -EINVAL; + goto fail; - spin_lock_irqsave(&sl811->lock, flags); ep = hep->hcpriv; if (ep) { /* finish right away if this urb can't be active ... @@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) VDBG("dequeue, urb %p active %s; wait4irq\n", urb, (sl811->active_a == ep) ? "A" : "B"); } else +fail: retval = -EINVAL; spin_unlock_irqrestore(&sl811->lock, flags); return retval; @@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd) if (sl811->board && sl811->board->power) hub_set_power_budget(udev, sl811->board->power * 2); + /* enable power and interupts */ + port_power(sl811, 1); + return 0; } @@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = { /*-------------------------------------------------------------------------*/ -static int __init_or_module +static int __devexit sl811h_remove(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); @@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev) remove_debug_file(sl811); usb_remove_hcd(hcd); - iounmap(sl811->data_reg); + /* some platforms may use IORESOURCE_IO */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - release_mem_region(res->start, 1); + if (res) + iounmap(sl811->data_reg); - iounmap(sl811->addr_reg); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(res->start, 1); + if (res) + iounmap(sl811->addr_reg); usb_put_hcd(hcd); return 0; } -#define resource_len(r) (((r)->end - (r)->start) + 1) - -static int __init +static int __devinit sl811h_probe(struct device *dev) { struct usb_hcd *hcd; @@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev) void __iomem *addr_reg; void __iomem *data_reg; int retval; - u8 tmp; + u8 tmp, ioaddr = 0; /* basic sanity checks first. board-specific init logic should * have initialized these three resources and probably board @@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev) * minimal sanity checking. */ pdev = container_of(dev, struct platform_device, dev); - if (pdev->num_resources < 3) - return -ENODEV; - - addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data = platform_get_resource(pdev, IORESOURCE_MEM, 1); irq = platform_get_irq(pdev, 0); - if (!addr || !data || irq < 0) + if (pdev->num_resources < 3 || irq < 0) return -ENODEV; /* refuse to confuse usbcore */ @@ -1679,24 +1686,31 @@ sl811h_probe(struct device *dev) return -EINVAL; } - if (!request_mem_region(addr->start, 1, hcd_name)) { - retval = -EBUSY; - goto err1; - } - addr_reg = ioremap(addr->start, resource_len(addr)); - if (addr_reg == NULL) { - retval = -ENOMEM; - goto err2; - } + /* the chip may be wired for either kind of addressing */ + addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); + data = platform_get_resource(pdev, IORESOURCE_MEM, 1); + retval = -EBUSY; + if (!addr || !data) { + addr = platform_get_resource(pdev, IORESOURCE_IO, 0); + data = platform_get_resource(pdev, IORESOURCE_IO, 1); + if (!addr || !data) + return -ENODEV; + ioaddr = 1; + + addr_reg = (void __iomem *) addr->start; + data_reg = (void __iomem *) data->start; + } else { + addr_reg = ioremap(addr->start, 1); + if (addr_reg == NULL) { + retval = -ENOMEM; + goto err2; + } - if (!request_mem_region(data->start, 1, hcd_name)) { - retval = -EBUSY; - goto err3; - } - data_reg = ioremap(data->start, resource_len(addr)); - if (data_reg == NULL) { - retval = -ENOMEM; - goto err4; + data_reg = ioremap(data->start, 1); + if (data_reg == NULL) { + retval = -ENOMEM; + goto err4; + } } /* allocate and initialize hcd */ @@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev) goto err6; } - /* sl811s would need a different handler for this irq */ -#ifdef CONFIG_ARM - /* Cypress docs say the IRQ is IRQT_HIGH ... */ - set_irq_type(irq, IRQT_RISING); -#endif - retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); + /* The chip's IRQ is level triggered, active high. A requirement + * for platform device setup is to cope with things like signal + * inverters (e.g. CF is active low) or working only with edge + * triggers (e.g. most ARM CPUs). Initial driver stress testing + * was on a system with single edge triggering, so most sorts of + * triggering arrangement should work. + */ + retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); if (retval != 0) goto err6; @@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev) err6: usb_put_hcd(hcd); err5: - iounmap(data_reg); + if (!ioaddr) + iounmap(data_reg); err4: - release_mem_region(data->start, 1); - err3: - iounmap(addr_reg); + if (!ioaddr) + iounmap(addr_reg); err2: - release_mem_region(addr->start, 1); - err1: DBG("init error, %d\n", retval); return retval; } @@ -1767,7 +1781,7 @@ sl811h_probe(struct device *dev) #ifdef CONFIG_PM /* for this device there's no useful distinction between the controller - * and its root hub, except that the root hub only gets direct PM calls + * and its root hub, except that the root hub only gets direct PM calls * when CONFIG_USB_SUSPEND is enabled. */ @@ -1821,20 +1835,22 @@ sl811h_resume(struct device *dev, u32 phase) #endif -static struct device_driver sl811h_driver = { +/* this driver is exported so sl811_cs can depend on it */ +struct device_driver sl811h_driver = { .name = (char *) hcd_name, .bus = &platform_bus_type, .probe = sl811h_probe, - .remove = sl811h_remove, + .remove = __devexit_p(sl811h_remove), .suspend = sl811h_suspend, .resume = sl811h_resume, }; +EXPORT_SYMBOL(sl811h_driver); /*-------------------------------------------------------------------------*/ - -static int __init sl811h_init(void) + +static int __init sl811h_init(void) { if (usb_disabled()) return -ENODEV; @@ -1844,8 +1860,8 @@ static int __init sl811h_init(void) } module_init(sl811h_init); -static void __exit sl811h_cleanup(void) -{ +static void __exit sl811h_cleanup(void) +{ driver_unregister(&sl811h_driver); } module_exit(sl811h_cleanup); -- cgit v1.2.2 From c6de2b64eb575a3f9326969ec5fcdc6032b38e42 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Thu, 26 May 2005 05:55:55 -0700 Subject: [PATCH] USB: add sl811_cs support This adds support for a CF-card USB Host adapter, the Ratoc REX-CFU1U, by wrapping a PCMCIA driver around the existing "sl811-hcd" platform driver. This CF card is especially useful for PDAs, which currently tend to have no other solution for USB host capability. From: Botond Botyanszki Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 11 ++ drivers/usb/host/Makefile | 1 + drivers/usb/host/sl811_cs.c | 442 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 drivers/usb/host/sl811_cs.c (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3196c3265ff5..19e598c9641f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -124,3 +124,14 @@ config USB_SL811_HCD To compile this driver as a module, choose M here: the module will be called sl811-hcd. +config USB_SL811_CS + tristate "CF/PCMCIA support for SL811HS HCD" + depends on USB_SL811_HCD && PCMCIA + default N + help + Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC + REX-CFU1U CF card (often used with PDAs). If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called "sl811_cs". + diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index a574ca06cf6b..5dbd3e7a27c7 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o +obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c new file mode 100644 index 000000000000..6e173265095c --- /dev/null +++ b/drivers/usb/host/sl811_cs.c @@ -0,0 +1,442 @@ +/* + * PCMCIA driver for SL811HS (as found in REX-CFU1U) + * Filename: sl811_cs.c + * Author: Yukio Yamamoto + * + * Port to sl811-hcd and 2.6.x by + * Botond Botyanszki + * Simon Pickering + * + * Last update: 2005-05-12 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +MODULE_AUTHOR("Botond Botyanszki"); +MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); +MODULE_LICENSE("GPL"); + + +/*====================================================================*/ +/* MACROS */ +/*====================================================================*/ + +#if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) + +static int pc_debug = 0; +module_param(pc_debug, int, 0644); + +#define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) + +#else +#define DBG(n, args...) do{}while(0) +#endif /* no debugging */ + +#define INFO(args...) printk(KERN_INFO "sl811_cs: " args) + +#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) + +#define CS_CHECK(fn, ret) \ + do { \ + last_fn = (fn); \ + if ((last_ret = (ret)) != 0) \ + goto cs_failed; \ + } while (0) + +/*====================================================================*/ +/* VARIABLES */ +/*====================================================================*/ + +static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; + +static dev_link_t *dev_list = NULL; + +static int irq_list[4] = { -1 }; +static int irq_list_count; + +module_param_array(irq_list, int, &irq_list_count, 0444); + +INT_MODULE_PARM(irq_mask, 0xdeb8); + +typedef struct local_info_t { + dev_link_t link; + dev_node_t node; +} local_info_t; + +/*====================================================================*/ + +static void release_platform_dev(struct device * dev) +{ + DBG(0, "sl811_cs platform_dev release\n"); + dev->parent = NULL; +} + +static struct sl811_platform_data platform_data = { + .potpg = 100, + .power = 50, /* == 100mA */ + // .reset = ... FIXME: invoke CF reset on the card +}; + +static struct resource resources[] = { + [0] = { + .flags = IORESOURCE_IRQ, + }, + [1] = { + // .name = "address", + .flags = IORESOURCE_IO, + }, + [2] = { + // .name = "data", + .flags = IORESOURCE_IO, + }, +}; + +extern struct device_driver sl811h_driver; + +static struct platform_device platform_dev = { + .id = -1, + .dev = { + .platform_data = &platform_data, + .release = release_platform_dev, + }, + .resource = resources, + .num_resources = ARRAY_SIZE(resources), +}; + +static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) +{ + if (platform_dev.dev.parent) + return -EBUSY; + platform_dev.dev.parent = parent; + + /* finish seting up the platform device */ + resources[0].start = irq; + + resources[1].start = base_addr; + resources[1].end = base_addr; + + resources[2].start = base_addr + 1; + resources[2].end = base_addr + 1; + + /* The driver core will probe for us. We know sl811-hcd has been + * initialized already because of the link order dependency. + */ + platform_dev.name = sl811h_driver.name; + return platform_device_register(&platform_dev); +} + +/*====================================================================*/ + +static void sl811_cs_detach(dev_link_t *link) +{ + dev_link_t **linkp; + + DBG(0, "sl811_cs_detach(0x%p)\n", link); + + /* Locate device structure */ + for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { + if (*linkp == link) + break; + } + if (*linkp == NULL) + return; + + /* Break the link with Card Services */ + if (link->handle) + pcmcia_deregister_client(link->handle); + + /* Unlink device structure, and free it */ + *linkp = link->next; + /* This points to the parent local_info_t struct */ + kfree(link->priv); +} + +static void sl811_cs_release(dev_link_t * link) +{ + + DBG(0, "sl811_cs_release(0x%p)\n", link); + + if (link->open) { + DBG(1, "sl811_cs: release postponed, '%s' still open\n", + link->dev->dev_name); + link->state |= DEV_STALE_CONFIG; + return; + } + + /* Unlink the device chain */ + link->dev = NULL; + + platform_device_unregister(&platform_dev); + pcmcia_release_configuration(link->handle); + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + if (link->irq.AssignedIRQ) + pcmcia_release_irq(link->handle, &link->irq); + link->state &= ~DEV_CONFIG; + + if (link->state & DEV_STALE_LINK) + sl811_cs_detach(link); +} + +static void sl811_cs_config(dev_link_t *link) +{ + client_handle_t handle = link->handle; + struct device *parent = &handle_to_dev(handle); + local_info_t *dev = link->priv; + tuple_t tuple; + cisparse_t parse; + int last_fn, last_ret; + u_char buf[64]; + config_info_t conf; + cistpl_cftable_entry_t dflt = { 0 }; + + DBG(0, "sl811_cs_config(0x%p)\n", link); + + tuple.DesiredTuple = CISTPL_CONFIG; + tuple.Attributes = 0; + tuple.TupleData = buf; + tuple.TupleDataMax = sizeof(buf); + tuple.TupleOffset = 0; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); + CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); + link->conf.ConfigBase = parse.config.base; + link->conf.Present = parse.config.rmask[0]; + + /* Configure card */ + link->state |= DEV_CONFIG; + + /* Look up the current Vcc */ + CS_CHECK(GetConfigurationInfo, + pcmcia_get_configuration_info(handle, &conf)); + link->conf.Vcc = conf.Vcc; + + tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; + CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); + while (1) { + cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); + + if (pcmcia_get_tuple_data(handle, &tuple) != 0 + || pcmcia_parse_tuple(handle, &tuple, &parse) + != 0) + goto next_entry; + + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { + dflt = *cfg; + } + + if (cfg->index == 0) + goto next_entry; + + link->conf.ConfigIndex = cfg->index; + + /* Use power settings for Vcc and Vpp if present */ + /* Note that the CIS values need to be rescaled */ + if (cfg->vcc.present & (1<vcc.param[CISTPL_POWER_VNOM]/10000 + != conf.Vcc) + goto next_entry; + } else if (dflt.vcc.present & (1<vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = + cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; + else if (dflt.vpp1.present & (1<conf.Vpp1 = link->conf.Vpp2 = + dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; + + /* we need an interrupt */ + if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) + link->conf.Attributes |= CONF_ENABLE_IRQ; + + /* IO window settings */ + link->io.NumPorts1 = link->io.NumPorts2 = 0; + if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { + cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; + + link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; + link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; + link->io.BasePort1 = io->win[0].base; + link->io.NumPorts1 = io->win[0].len; + + if (pcmcia_request_io(link->handle, &link->io) != 0) + goto next_entry; + } + break; + +next_entry: + if (link->io.NumPorts1) + pcmcia_release_io(link->handle, &link->io); + last_ret = pcmcia_get_next_tuple(handle, &tuple); + } + + /* require an IRQ and two registers */ + if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) + goto cs_failed; + if (link->conf.Attributes & CONF_ENABLE_IRQ) + CS_CHECK(RequestIRQ, + pcmcia_request_irq(link->handle, &link->irq)); + else + goto cs_failed; + + CS_CHECK(RequestConfiguration, + pcmcia_request_configuration(link->handle, &link->conf)); + + sprintf(dev->node.dev_name, driver_name); + dev->node.major = dev->node.minor = 0; + link->dev = &dev->node; + + printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", + dev->node.dev_name, link->conf.ConfigIndex, + link->conf.Vcc/10, link->conf.Vcc%10); + if (link->conf.Vpp1) + printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); + printk(", irq %d", link->irq.AssignedIRQ); + printk(", io 0x%04x-0x%04x", link->io.BasePort1, + link->io.BasePort1+link->io.NumPorts1-1); + printk("\n"); + + link->state &= ~DEV_CONFIG_PENDING; + + if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) + < 0) { +cs_failed: + printk("sl811_cs_config failed\n"); + cs_error(link->handle, last_fn, last_ret); + sl811_cs_release(link); + link->state &= ~DEV_CONFIG_PENDING; + } +} + +static int +sl811_cs_event(event_t event, int priority, event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + + DBG(1, "sl811_cs_event(0x%06x)\n", event); + + switch (event) { + case CS_EVENT_CARD_REMOVAL: + link->state &= ~DEV_PRESENT; + if (link->state & DEV_CONFIG) + sl811_cs_release(link); + break; + + case CS_EVENT_CARD_INSERTION: + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + sl811_cs_config(link); + break; + + case CS_EVENT_PM_SUSPEND: + link->state |= DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_RESET_PHYSICAL: + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + break; + + case CS_EVENT_PM_RESUME: + link->state &= ~DEV_SUSPEND; + /* Fall through... */ + case CS_EVENT_CARD_RESET: + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + DBG(0, "reset sl811-hcd here?\n"); + break; + } + return 0; +} + +static dev_link_t *sl811_cs_attach(void) +{ + local_info_t *local; + dev_link_t *link; + client_reg_t client_reg; + int ret, i; + + local = kmalloc(sizeof(local_info_t), GFP_KERNEL); + if (!local) + return NULL; + memset(local, 0, sizeof(local_info_t)); + link = &local->link; + link->priv = local; + + /* Initialize */ + link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; + if (irq_list[0] == -1) + link->irq.IRQInfo2 = irq_mask; + else + for (i = 0; i < irq_list_count; i++) + link->irq.IRQInfo2 |= 1 << irq_list[i]; + link->irq.Handler = NULL; + + link->conf.Attributes = 0; + link->conf.Vcc = 33; + link->conf.IntType = INT_MEMORY_AND_IO; + + /* Register with Card Services */ + link->next = dev_list; + dev_list = link; + client_reg.dev_info = (dev_info_t *) &driver_name; + client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; + client_reg.EventMask = + CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | + CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | + CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; + client_reg.event_handler = &sl811_cs_event; + client_reg.Version = 0x0210; + client_reg.event_callback_args.client_data = link; + ret = pcmcia_register_client(&link->handle, &client_reg); + if (ret != CS_SUCCESS) { + cs_error(link->handle, RegisterClient, ret); + sl811_cs_detach(link); + return NULL; + } + + return link; +} + +static struct pcmcia_driver sl811_cs_driver = { + .owner = THIS_MODULE, + .drv = { + .name = (char *)driver_name, + }, + .attach = sl811_cs_attach, + .detach = sl811_cs_detach, +}; + +/*====================================================================*/ + +static int __init init_sl811_cs(void) +{ + return pcmcia_register_driver(&sl811_cs_driver); +} +module_init(init_sl811_cs); + +static void __exit exit_sl811_cs(void) +{ + pcmcia_unregister_driver(&sl811_cs_driver); +} +module_exit(exit_sl811_cs); -- cgit v1.2.2 From 47900743a56dc41a053107d64054aca3e1b42157 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 17 May 2005 15:12:13 +0100 Subject: [PATCH] USB: ftdi_sio: new PID for ELV UM100 ftdi_sio: Add PID for "ELV USB Module UM100". PID sent by Armin Laugher. Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 3 +++ drivers/usb/serial/ftdi_sio.h | 2 ++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 52394f08a947..051c3a77b41b 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -364,6 +364,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, @@ -475,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, @@ -618,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index a52bb13a9ce4..8866376823a5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -144,6 +144,8 @@ /* ELV USB Module UO100 (PID sent by Stefan Frings) */ #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ +/* ELV USB Module UM100 (PID sent by Arnim Laeuger) */ +#define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */ /* * Definitions for ID TECH (www.idt-net.com) devices -- cgit v1.2.2 From 06299db3e7f857a4985cf70dc1a5049ec12482c1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 26 May 2005 05:55:55 -0700 Subject: [PATCH] USB: fix usb-serial generic initialization At module load time, if a generic device is found, the tty information for the device is not set up properly (as the tty structures aren't initialized yet.) This can cause big problems for things like udev. This patch fixes this. Thanks to Kay Sievers for the original patch for this problem. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4536f63faaea..5da76dd8fb28 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -1297,13 +1297,6 @@ static int __init usb_serial_init(void) goto exit_bus; } - /* register the generic driver, if we should */ - result = usb_serial_generic_register(debug); - if (result < 0) { - err("%s - registering generic driver failed", __FUNCTION__); - goto exit_generic; - } - usb_serial_tty_driver->owner = THIS_MODULE; usb_serial_tty_driver->driver_name = "usbserial"; usb_serial_tty_driver->devfs_name = "usb/tts/"; @@ -1329,17 +1322,24 @@ static int __init usb_serial_init(void) goto exit_tty; } + /* register the generic driver, if we should */ + result = usb_serial_generic_register(debug); + if (result < 0) { + err("%s - registering generic driver failed", __FUNCTION__); + goto exit_generic; + } + info(DRIVER_DESC " " DRIVER_VERSION); return result; +exit_generic: + usb_deregister(&usb_serial_driver); + exit_tty: tty_unregister_driver(usb_serial_tty_driver); exit_reg_driver: - usb_serial_generic_deregister(); - -exit_generic: bus_unregister(&usb_serial_bus_type); exit_bus: -- cgit v1.2.2 From 7a8cb869f31de525bc34095f51f8c8a43ffcb6a9 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Mon, 23 May 2005 19:50:32 +0900 Subject: [PATCH] PCI Hotplug: shpchp driver doesn't program _HPP values properly Current shpchp driver doesn't seem to program _HPP values properly. The following patch fixes this issue. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchprm_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 243a51d88b86..18aa65a206a6 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -1626,7 +1626,7 @@ int shpchprm_set_hpp( pci_bus->number = func->bus; devfn = PCI_DEVFN(func->device, func->function); - ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); + ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); if (ab) { if (ab->_hpp) { -- cgit v1.2.2 From 2ac2610b26c9da72820443328ff2c56c7b8c87b8 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Fri, 27 May 2005 16:08:14 +0900 Subject: [PATCH] PCI Hotplug: SHPCHP driver doesn't enable PERR and SERR properly Current shpchp driver doesn't seem to program command register to enable PERR and SERR properly. The following patch fixes this issue. Signed-off-by: Kenji Kaneshige Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/shpchprm_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/shpchprm_acpi.c b/drivers/pci/hotplug/shpchprm_acpi.c index 18aa65a206a6..7957cdc72cd0 100644 --- a/drivers/pci/hotplug/shpchprm_acpi.c +++ b/drivers/pci/hotplug/shpchprm_acpi.c @@ -1681,7 +1681,7 @@ void shpchprm_enable_card( | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; bcmd = bcommand = bcommand | PCI_BRIDGE_CTL_NO_ISA; - ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->bus); + ab = find_acpi_bridge_by_bus(acpi_bridges_head, ctrl->seg, ctrl->slot_bus); if (ab) { if (ab->_hpp) { if (ab->_hpp->enable_perr) { -- cgit v1.2.2 From af00f9811e0ccbd3db84ddc4cffb0da942653393 Mon Sep 17 00:00:00 2001 From: Andy Currid Date: Mon, 23 May 2005 08:55:45 -0700 Subject: [PATCH] PCI: amd74xx patch for new NVIDIA device IDs Here's the 2.6 amd74xx patch for NVIDIA MCP51. Signed-off-by: Andy Currid Signed-off-by: Greg Kroah-Hartman --- drivers/ide/pci/amd74xx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 47225e324356..4e0f13d1d060 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -72,6 +72,7 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, { 0 } }; @@ -487,6 +488,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 12 */ DECLARE_NV_DEV("NFORCE3-250-SATA2"), /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), + /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -521,6 +523,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { #endif { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); -- cgit v1.2.2 From bcc488ab02254a6e60d749187a632dc3d642d4f8 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Fri, 27 May 2005 16:48:52 -0400 Subject: [PATCH] PCI Hotplug: more CPCI updates Here is my third attempt at a patch to further update the CompactPCI hotplug driver infrastructure to address the pci_enable_device issue discussed on the list as well as a few other issues I discovered during some more testing. This version addresses a few more issues pointed out by Prarit Bhargava. Changes include: - cpci_enable_device and its recursive calling of pci_enable_device on new devices removed. - Use list_rwsem to avoid slot status change races between disable_slot and check_slots. - Fixed oopsing in cpci_hp_unregister_bus caused by calling list_del on a slot after calling pci_hp_deregister. - Removed kfree calls in cleanup_slots since release_slot will have done it already. - Reworked init_slots a bit to fix latch and adapter file updating on subsequent calls to cpci_hp_start. - Improved sanity checking in cpci_hp_register_controller. - Now shut things down correctly in cpci_hotplug_exit. - Switch to pci_get_slot instead of deprecated pci_find_slot. - A bunch of CodingStyle fixes. Signed-off-by: Scott Murray Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpci_hotplug_core.c | 302 +++++++++++++++----------------- drivers/pci/hotplug/cpci_hotplug_pci.c | 144 ++++++--------- 2 files changed, 192 insertions(+), 254 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 9e9dab7fe86a..8132d946c384 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -1,7 +1,7 @@ /* * CompactPCI Hot Plug Driver * - * Copyright (C) 2002 SOMA Networks, Inc. + * Copyright (C) 2002,2005 SOMA Networks, Inc. * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) * Copyright (C) 2001 IBM Corp. * @@ -45,10 +45,10 @@ #define dbg(format, arg...) \ do { \ - if(cpci_debug) \ + if (cpci_debug) \ printk (KERN_DEBUG "%s: " format "\n", \ MY_NAME , ## arg); \ - } while(0) + } while (0) #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) @@ -111,10 +111,8 @@ enable_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); - if(controller->ops->set_power) { + if (controller->ops->set_power) retval = controller->ops->set_power(slot, 1); - } - return retval; } @@ -126,37 +124,41 @@ disable_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s", __FUNCTION__, hotplug_slot->name); + down_write(&list_rwsem); + /* Unconfigure device */ dbg("%s - unconfiguring slot %s", __FUNCTION__, slot->hotplug_slot->name); - if((retval = cpci_unconfigure_slot(slot))) { + if ((retval = cpci_unconfigure_slot(slot))) { err("%s - could not unconfigure slot %s", __FUNCTION__, slot->hotplug_slot->name); - return retval; + goto disable_error; } dbg("%s - finished unconfiguring slot %s", __FUNCTION__, slot->hotplug_slot->name); /* Clear EXT (by setting it) */ - if(cpci_clear_ext(slot)) { + if (cpci_clear_ext(slot)) { err("%s - could not clear EXT for slot %s", __FUNCTION__, slot->hotplug_slot->name); retval = -ENODEV; + goto disable_error; } cpci_led_on(slot); - if(controller->ops->set_power) { - retval = controller->ops->set_power(slot, 0); - } + if (controller->ops->set_power) + if ((retval = controller->ops->set_power(slot, 0))) + goto disable_error; - if(update_adapter_status(slot->hotplug_slot, 0)) { + if (update_adapter_status(slot->hotplug_slot, 0)) warn("failure to update adapter file"); - } - if(slot->extracting) { + if (slot->extracting) { slot->extracting = 0; atomic_dec(&extracting); } +disable_error: + up_write(&list_rwsem); return retval; } @@ -165,9 +167,8 @@ cpci_get_power_status(struct slot *slot) { u8 power = 1; - if(controller->ops->get_power) { + if (controller->ops->get_power) power = controller->ops->get_power(slot); - } return power; } @@ -237,9 +238,8 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) int status = -ENOMEM; int i; - if(!(controller && bus)) { + if (!(controller && bus)) return -ENODEV; - } /* * Create a structure for each slot, and register that slot @@ -316,32 +316,30 @@ int cpci_hp_unregister_bus(struct pci_bus *bus) { struct slot *slot; - struct list_head *tmp; - struct list_head *next; - int status; + struct slot *tmp; + int status = 0; down_write(&list_rwsem); - if(!slots) { + if (!slots) { up_write(&list_rwsem); return -1; } - list_for_each_safe(tmp, next, &slot_list) { - slot = list_entry(tmp, struct slot, slot_list); - if(slot->bus == bus) { + list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { + if (slot->bus == bus) { + list_del(&slot->slot_list); + slots--; + dbg("deregistering slot %s", slot->hotplug_slot->name); status = pci_hp_deregister(slot->hotplug_slot); - if(status) { + if (status) { err("pci_hp_deregister failed with error %d", status); - return status; + break; } - - list_del(&slot->slot_list); - slots--; } } up_write(&list_rwsem); - return 0; + return status; } /* This is the interrupt mode interrupt handler */ @@ -351,7 +349,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) dbg("entered cpci_hp_intr"); /* Check to see if it was our interrupt */ - if((controller->irq_flags & SA_SHIRQ) && + if ((controller->irq_flags & SA_SHIRQ) && !controller->ops->check_irq(controller->dev_id)) { dbg("exited cpci_hp_intr, not our interrupt"); return IRQ_NONE; @@ -373,38 +371,30 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) * INS bits of the cold-inserted devices. */ static int -init_slots(void) +init_slots(int clear_ins) { struct slot *slot; - struct list_head *tmp; struct pci_dev* dev; dbg("%s - enter", __FUNCTION__); down_read(&list_rwsem); - if(!slots) { + if (!slots) { up_read(&list_rwsem); return -1; } - list_for_each(tmp, &slot_list) { - slot = list_entry(tmp, struct slot, slot_list); + list_for_each_entry(slot, &slot_list, slot_list) { dbg("%s - looking at slot %s", __FUNCTION__, slot->hotplug_slot->name); - if(cpci_check_and_clear_ins(slot)) { + if (clear_ins && cpci_check_and_clear_ins(slot)) dbg("%s - cleared INS for slot %s", __FUNCTION__, slot->hotplug_slot->name); - dev = pci_find_slot(slot->bus->number, PCI_DEVFN(slot->number, 0)); - if(dev) { - if(update_adapter_status(slot->hotplug_slot, 1)) { - warn("failure to update adapter file"); - } - if(update_latch_status(slot->hotplug_slot, 1)) { - warn("failure to update latch file"); - } - slot->dev = dev; - } else { - err("%s - no driver attached to device in slot %s", - __FUNCTION__, slot->hotplug_slot->name); - } + dev = pci_get_slot(slot->bus, PCI_DEVFN(slot->number, 0)); + if (dev) { + if (update_adapter_status(slot->hotplug_slot, 1)) + warn("failure to update adapter file"); + if (update_latch_status(slot->hotplug_slot, 1)) + warn("failure to update latch file"); + slot->dev = dev; } } up_read(&list_rwsem); @@ -416,26 +406,28 @@ static int check_slots(void) { struct slot *slot; - struct list_head *tmp; int extracted; int inserted; u16 hs_csr; down_read(&list_rwsem); - if(!slots) { + if (!slots) { up_read(&list_rwsem); err("no slots registered, shutting down"); return -1; } extracted = inserted = 0; - list_for_each(tmp, &slot_list) { - slot = list_entry(tmp, struct slot, slot_list); + list_for_each_entry(slot, &slot_list, slot_list) { dbg("%s - looking at slot %s", __FUNCTION__, slot->hotplug_slot->name); - if(cpci_check_and_clear_ins(slot)) { - /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ - if(slot->dev) { - warn("slot %s already inserted", slot->hotplug_slot->name); + if (cpci_check_and_clear_ins(slot)) { + /* + * Some broken hardware (e.g. PLX 9054AB) asserts + * ENUM# twice... + */ + if (slot->dev) { + warn("slot %s already inserted", + slot->hotplug_slot->name); inserted++; continue; } @@ -452,7 +444,7 @@ check_slots(void) /* Configure device */ dbg("%s - configuring slot %s", __FUNCTION__, slot->hotplug_slot->name); - if(cpci_configure_slot(slot)) { + if (cpci_configure_slot(slot)) { err("%s - could not configure slot %s", __FUNCTION__, slot->hotplug_slot->name); continue; @@ -465,13 +457,11 @@ check_slots(void) dbg("%s - slot %s HS_CSR (2) = %04x", __FUNCTION__, slot->hotplug_slot->name, hs_csr); - if(update_latch_status(slot->hotplug_slot, 1)) { + if (update_latch_status(slot->hotplug_slot, 1)) warn("failure to update latch file"); - } - if(update_adapter_status(slot->hotplug_slot, 1)) { + if (update_adapter_status(slot->hotplug_slot, 1)) warn("failure to update adapter file"); - } cpci_led_off(slot); @@ -481,7 +471,7 @@ check_slots(void) __FUNCTION__, slot->hotplug_slot->name, hs_csr); inserted++; - } else if(cpci_check_ext(slot)) { + } else if (cpci_check_ext(slot)) { /* Process extraction request */ dbg("%s - slot %s extracted", __FUNCTION__, slot->hotplug_slot->name); @@ -491,27 +481,25 @@ check_slots(void) dbg("%s - slot %s HS_CSR = %04x", __FUNCTION__, slot->hotplug_slot->name, hs_csr); - if(!slot->extracting) { - if(update_latch_status(slot->hotplug_slot, 0)) { + if (!slot->extracting) { + if (update_latch_status(slot->hotplug_slot, 0)) { warn("failure to update latch file"); - } - atomic_inc(&extracting); slot->extracting = 1; + atomic_inc(&extracting); } extracted++; - } else if(slot->extracting) { + } else if (slot->extracting) { hs_csr = cpci_get_hs_csr(slot); - if(hs_csr == 0xffff) { + if (hs_csr == 0xffff) { /* * Hmmm, we're likely hosed at this point, should we * bother trying to tell the driver or not? */ err("card in slot %s was improperly removed", slot->hotplug_slot->name); - if(update_adapter_status(slot->hotplug_slot, 0)) { + if (update_adapter_status(slot->hotplug_slot, 0)) warn("failure to update adapter file"); - } slot->extracting = 0; atomic_dec(&extracting); } @@ -520,10 +508,9 @@ check_slots(void) up_read(&list_rwsem); dbg("inserted=%d, extracted=%d, extracting=%d", inserted, extracted, atomic_read(&extracting)); - if(inserted || extracted) { + if (inserted || extracted) return extracted; - } - else if(!atomic_read(&extracting)) { + else if (!atomic_read(&extracting)) { err("cannot find ENUM# source, shutting down"); return -1; } @@ -541,12 +528,12 @@ event_thread(void *data) unlock_kernel(); dbg("%s - event thread started", __FUNCTION__); - while(1) { + while (1) { dbg("event thread sleeping"); down_interruptible(&event_semaphore); dbg("event thread woken, thread_finished = %d", thread_finished); - if(thread_finished || signal_pending(current)) + if (thread_finished || signal_pending(current)) break; do { rc = check_slots(); @@ -558,7 +545,9 @@ event_thread(void *data) thread_finished = 1; break; } - } while(atomic_read(&extracting) != 0); + } while (atomic_read(&extracting) && !thread_finished); + if (thread_finished) + break; /* Re-enable ENUM# interrupt */ dbg("%s - re-enabling irq", __FUNCTION__); @@ -579,21 +568,21 @@ poll_thread(void *data) daemonize("cpci_hp_polld"); unlock_kernel(); - while(1) { - if(thread_finished || signal_pending(current)) + while (1) { + if (thread_finished || signal_pending(current)) break; - if(controller->ops->query_enum()) { + if (controller->ops->query_enum()) { do { rc = check_slots(); - if(rc > 0) { + if (rc > 0) { /* Give userspace a chance to handle extraction */ msleep(500); - } else if(rc < 0) { + } else if (rc < 0) { dbg("%s - error checking slots", __FUNCTION__); thread_finished = 1; break; } - } while(atomic_read(&extracting) != 0); + } while (atomic_read(&extracting) && !thread_finished); } msleep(100); } @@ -612,12 +601,11 @@ cpci_start_thread(void) init_MUTEX_LOCKED(&thread_exit); thread_finished = 0; - if(controller->irq) { + if (controller->irq) pid = kernel_thread(event_thread, NULL, 0); - } else { + else pid = kernel_thread(poll_thread, NULL, 0); - } - if(pid < 0) { + if (pid < 0) { err("Can't start up our thread"); return -1; } @@ -630,9 +618,8 @@ cpci_stop_thread(void) { thread_finished = 1; dbg("thread finish command given"); - if(controller->irq) { + if (controller->irq) up(&event_semaphore); - } dbg("wait for thread to exit"); down(&thread_exit); } @@ -642,45 +629,67 @@ cpci_hp_register_controller(struct cpci_hp_controller *new_controller) { int status = 0; - if(!controller) { - controller = new_controller; - if(controller->irq) { - if(request_irq(controller->irq, - cpci_hp_intr, - controller->irq_flags, - MY_NAME, controller->dev_id)) { - err("Can't get irq %d for the hotplug cPCI controller", controller->irq); - status = -ENODEV; - } - dbg("%s - acquired controller irq %d", __FUNCTION__, - controller->irq); + if (controller) + return -1; + if (!(new_controller && new_controller->ops)) + return -EINVAL; + if (new_controller->irq) { + if (!(new_controller->ops->enable_irq && + new_controller->ops->disable_irq)) + status = -EINVAL; + if (request_irq(new_controller->irq, + cpci_hp_intr, + new_controller->irq_flags, + MY_NAME, + new_controller->dev_id)) { + err("Can't get irq %d for the hotplug cPCI controller", + new_controller->irq); + status = -ENODEV; } - } else { - err("cPCI hotplug controller already registered"); - status = -1; + dbg("%s - acquired controller irq %d", + __FUNCTION__, new_controller->irq); } + if (!status) + controller = new_controller; return status; } +static void +cleanup_slots(void) +{ + struct slot *slot; + struct slot *tmp; + + /* + * Unregister all of our slots with the pci_hotplug subsystem, + * and free up all memory that we had allocated. + */ + down_write(&list_rwsem); + if (!slots) + goto cleanup_null; + list_for_each_entry_safe(slot, tmp, &slot_list, slot_list) { + list_del(&slot->slot_list); + pci_hp_deregister(slot->hotplug_slot); + } +cleanup_null: + up_write(&list_rwsem); + return; +} + int cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) { int status = 0; - if(controller) { - if(atomic_read(&extracting) != 0) { - return -EBUSY; - } - if(!thread_finished) { + if (controller) { + if (!thread_finished) cpci_stop_thread(); - } - if(controller->irq) { + if (controller->irq) free_irq(controller->irq, controller->dev_id); - } controller = NULL; - } else { + cleanup_slots(); + } else status = -ENODEV; - } return status; } @@ -691,32 +700,28 @@ cpci_hp_start(void) int status; dbg("%s - enter", __FUNCTION__); - if(!controller) { + if (!controller) return -ENODEV; - } down_read(&list_rwsem); - if(list_empty(&slot_list)) { + if (list_empty(&slot_list)) { up_read(&list_rwsem); return -ENODEV; } up_read(&list_rwsem); - if(first) { - status = init_slots(); - if(status) { - return status; - } + status = init_slots(first); + if (first) first = 0; - } + if (status) + return status; status = cpci_start_thread(); - if(status) { + if (status) return status; - } dbg("%s - thread started", __FUNCTION__); - if(controller->irq) { + if (controller->irq) { /* Start enum interrupt processing */ dbg("%s - enabling irq", __FUNCTION__); controller->ops->enable_irq(); @@ -728,13 +733,9 @@ cpci_hp_start(void) int cpci_hp_stop(void) { - if(!controller) { + if (!controller) return -ENODEV; - } - if(atomic_read(&extracting) != 0) { - return -EBUSY; - } - if(controller->irq) { + if (controller->irq) { /* Stop enum interrupt processing */ dbg("%s - disabling irq", __FUNCTION__); controller->ops->disable_irq(); @@ -743,34 +744,6 @@ cpci_hp_stop(void) return 0; } -static void __exit -cleanup_slots(void) -{ - struct list_head *tmp; - struct slot *slot; - - /* - * Unregister all of our slots with the pci_hotplug subsystem, - * and free up all memory that we had allocated. - */ - down_write(&list_rwsem); - if(!slots) { - goto null_cleanup; - } - list_for_each(tmp, &slot_list) { - slot = list_entry(tmp, struct slot, slot_list); - list_del(&slot->slot_list); - pci_hp_deregister(slot->hotplug_slot); - kfree(slot->hotplug_slot->info); - kfree(slot->hotplug_slot->name); - kfree(slot->hotplug_slot); - kfree(slot); - } - null_cleanup: - up_write(&list_rwsem); - return; -} - int __init cpci_hotplug_init(int debug) { @@ -784,7 +757,8 @@ cpci_hotplug_exit(void) /* * Clean everything up. */ - cleanup_slots(); + cpci_hp_stop(); + cpci_hp_unregister_controller(controller); } EXPORT_SYMBOL_GPL(cpci_hp_register_controller); diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 69eb4fc54f2f..c878028ad215 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -1,7 +1,7 @@ /* * CompactPCI Hot Plug Driver PCI functions * - * Copyright (C) 2002 by SOMA Networks, Inc. + * Copyright (C) 2002,2005 by SOMA Networks, Inc. * * All rights reserved. * @@ -38,10 +38,10 @@ extern int cpci_debug; #define dbg(format, arg...) \ do { \ - if(cpci_debug) \ + if (cpci_debug) \ printk (KERN_DEBUG "%s: " format "\n", \ MY_NAME , ## arg); \ - } while(0) + } while (0) #define err(format, arg...) printk(KERN_ERR "%s: " format "\n", MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) @@ -57,16 +57,15 @@ u8 cpci_get_attention_status(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return 0; - } - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return 0; - } + return hs_csr & 0x0008 ? 1 : 0; } @@ -78,27 +77,22 @@ int cpci_set_attention_status(struct slot* slot, int status) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return 0; - } - - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return 0; - } - if(status) { + if (status) hs_csr |= HS_CSR_LOO; - } else { + else hs_csr &= ~HS_CSR_LOO; - } - if(pci_bus_write_config_word(slot->bus, + if (pci_bus_write_config_word(slot->bus, slot->devfn, hs_cap + 2, - hs_csr)) { + hs_csr)) return 0; - } return 1; } @@ -110,16 +104,13 @@ u16 cpci_get_hs_csr(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return 0xFFFF; - } - - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return 0xFFFF; - } return hs_csr; } @@ -132,24 +123,22 @@ int cpci_check_and_clear_ins(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return 0; - } - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return 0; - } - if(hs_csr & HS_CSR_INS) { + if (hs_csr & HS_CSR_INS) { /* Clear INS (by setting it) */ - if(pci_bus_write_config_word(slot->bus, + if (pci_bus_write_config_word(slot->bus, slot->devfn, hs_cap + 2, - hs_csr)) { + hs_csr)) ins = 0; - } - ins = 1; + else + ins = 1; } return ins; } @@ -163,18 +152,15 @@ int cpci_check_ext(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return 0; - } - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return 0; - } - if(hs_csr & HS_CSR_EXT) { + if (hs_csr & HS_CSR_EXT) ext = 1; - } return ext; } @@ -186,23 +172,20 @@ int cpci_clear_ext(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return -ENODEV; - } - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return -ENODEV; - } - if(hs_csr & HS_CSR_EXT) { + if (hs_csr & HS_CSR_EXT) { /* Clear EXT (by setting it) */ - if(pci_bus_write_config_word(slot->bus, + if (pci_bus_write_config_word(slot->bus, slot->devfn, hs_cap + 2, - hs_csr)) { + hs_csr)) return -ENODEV; - } } return 0; } @@ -215,18 +198,16 @@ int cpci_led_on(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return -ENODEV; - } - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return -ENODEV; - } - if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { + if ((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { hs_csr |= HS_CSR_LOO; - if(pci_bus_write_config_word(slot->bus, + if (pci_bus_write_config_word(slot->bus, slot->devfn, hs_cap + 2, hs_csr)) { @@ -246,18 +227,16 @@ int cpci_led_off(struct slot* slot) hs_cap = pci_bus_find_capability(slot->bus, slot->devfn, PCI_CAP_ID_CHSWP); - if(!hs_cap) { + if (!hs_cap) return -ENODEV; - } - if(pci_bus_read_config_word(slot->bus, + if (pci_bus_read_config_word(slot->bus, slot->devfn, hs_cap + 2, - &hs_csr)) { + &hs_csr)) return -ENODEV; - } - if(hs_csr & HS_CSR_LOO) { + if (hs_csr & HS_CSR_LOO) { hs_csr &= ~HS_CSR_LOO; - if(pci_bus_write_config_word(slot->bus, + if (pci_bus_write_config_word(slot->bus, slot->devfn, hs_cap + 2, hs_csr)) { @@ -274,19 +253,6 @@ int cpci_led_off(struct slot* slot) * Device configuration functions */ -static void cpci_enable_device(struct pci_dev *dev) -{ - struct pci_bus *bus; - - pci_enable_device(dev); - if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - bus = dev->subordinate; - list_for_each_entry(dev, &bus->devices, bus_list) { - cpci_enable_device(dev); - } - } -} - int cpci_configure_slot(struct slot* slot) { unsigned char busnr; @@ -294,14 +260,14 @@ int cpci_configure_slot(struct slot* slot) dbg("%s - enter", __FUNCTION__); - if(slot->dev == NULL) { + if (slot->dev == NULL) { dbg("pci_dev null, finding %02x:%02x:%x", slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); - slot->dev = pci_find_slot(slot->bus->number, slot->devfn); + slot->dev = pci_get_slot(slot->bus, slot->devfn); } /* Still NULL? Well then scan for it! */ - if(slot->dev == NULL) { + if (slot->dev == NULL) { int n; dbg("pci_dev still null"); @@ -311,10 +277,10 @@ int cpci_configure_slot(struct slot* slot) */ n = pci_scan_slot(slot->bus, slot->devfn); dbg("%s: pci_scan_slot returned %d", __FUNCTION__, n); - if(n > 0) + if (n > 0) pci_bus_add_devices(slot->bus); - slot->dev = pci_find_slot(slot->bus->number, slot->devfn); - if(slot->dev == NULL) { + slot->dev = pci_get_slot(slot->bus, slot->devfn); + if (slot->dev == NULL) { err("Could not find PCI device for slot %02x", slot->number); return 1; } @@ -329,8 +295,6 @@ int cpci_configure_slot(struct slot* slot) pci_bus_assign_resources(slot->dev->bus); - cpci_enable_device(slot->dev); - dbg("%s - exit", __FUNCTION__); return 0; } @@ -341,15 +305,15 @@ int cpci_unconfigure_slot(struct slot* slot) struct pci_dev *dev; dbg("%s - enter", __FUNCTION__); - if(!slot->dev) { + if (!slot->dev) { err("No device for slot %02x\n", slot->number); return -ENODEV; } for (i = 0; i < 8; i++) { - dev = pci_find_slot(slot->bus->number, + dev = pci_get_slot(slot->bus, PCI_DEVFN(PCI_SLOT(slot->devfn), i)); - if(dev) { + if (dev) { pci_remove_bus_device(dev); slot->dev = NULL; } -- cgit v1.2.2 From 97d3a00f77fa527886d53dd943017654ce142186 Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Tue, 31 May 2005 14:39:30 -0700 Subject: [PATCH] pcdp.c build fix In file included from drivers/firmware/pcdp.c:18: drivers/firmware/pcdp.h:48: error: field `addr' has incomplete type drivers/firmware/pcdp.c: In function `setup_serial_console': drivers/firmware/pcdp.c:27: error: `ACPI_ADR_SPACE_SYSTEM_MEMORY' undeclared (first use in this function) Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/pcdp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 6d5df6c2efa2..df1b721154d2 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include #include #include #include -- cgit v1.2.2 From 78ee998fd46ed4cc647ee442d2a5492f389ee27a Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:43 -0700 Subject: [CPUFREQ] cpufreq-core: reduce warning messages. cpufreq core is printing out messages at KERN_WARNING level that the core recovers from without intervention, and that the system administrator can do nothing about. Patch below reduces the severity of these messages to debug. Signed-off-by: Matt Domsch Signed-off-by: Andrew Morton Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8e561313d094..03b5fb2ddcf4 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -258,7 +258,7 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state) (likely(cpufreq_cpu_data[freqs->cpu]->cur)) && (unlikely(freqs->old != cpufreq_cpu_data[freqs->cpu]->cur))) { - printk(KERN_WARNING "Warning: CPU frequency is %u, " + dprintk(KERN_WARNING "Warning: CPU frequency is %u, " "cpufreq assumed %u kHz.\n", freqs->old, cpufreq_cpu_data[freqs->cpu]->cur); freqs->old = cpufreq_cpu_data[freqs->cpu]->cur; } @@ -814,7 +814,7 @@ static void cpufreq_out_of_sync(unsigned int cpu, unsigned int old_freq, unsigne { struct cpufreq_freqs freqs; - printk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " + dprintk(KERN_WARNING "Warning: CPU frequency out of sync: cpufreq and timing " "core thinks of %u, is %u kHz.\n", old_freq, new_freq); freqs.cpu = cpu; @@ -923,7 +923,7 @@ static int cpufreq_suspend(struct sys_device * sysdev, u32 state) struct cpufreq_freqs freqs; if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) - printk(KERN_DEBUG "Warning: CPU frequency is %u, " + dprintk(KERN_DEBUG "Warning: CPU frequency is %u, " "cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur); @@ -1004,7 +1004,7 @@ static int cpufreq_resume(struct sys_device * sysdev) struct cpufreq_freqs freqs; if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN)) - printk(KERN_WARNING "Warning: CPU frequency" + dprintk(KERN_WARNING "Warning: CPU frequency" "is %u, cpufreq assumed %u kHz.\n", cur_freq, cpu_policy->cur); -- cgit v1.2.2 From 6fe711658fcf92d39d84c0b7e6332ed6625dc520 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:44 -0700 Subject: [CPUFREQ] ondemand: trivial clean-ups Trivial ondemand governor clean-ups: - change from sampling_rate_in_HZ() to the official function usecs_to_jiffies(). - use for_each_online_cpu() to instead of using "if (cpu_online(i))" Signed-off-by: Eric Piel Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dominik Brodowski Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 8d83a21c6477..0bc0bff55d26 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -57,7 +57,6 @@ static unsigned int def_sampling_rate; #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) #define DEF_SAMPLING_DOWN_FACTOR (10) #define TRANSITION_LATENCY_LIMIT (10 * 1000) -#define sampling_rate_in_HZ(x) (((x * HZ) < (1000 * 1000))?1:((x * HZ) / (1000 * 1000))) static void do_dbs_timer(void *data); @@ -281,7 +280,7 @@ static void dbs_check_cpu(int cpu) /* Scale idle ticks by 100 and compare with up and down ticks */ idle_ticks *= 100; up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * - sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate); + usecs_to_jiffies(dbs_tuners_ins.sampling_rate); if (idle_ticks < up_idle_ticks) { __cpufreq_driver_target(policy, policy->max, @@ -328,7 +327,7 @@ static void dbs_check_cpu(int cpu) freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * dbs_tuners_ins.sampling_down_factor; down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * - sampling_rate_in_HZ(freq_down_sampling_rate); + usecs_to_jiffies(freq_down_sampling_rate); if (idle_ticks > down_idle_ticks ) { freq_down_step = (5 * policy->max) / 100; @@ -348,11 +347,10 @@ static void do_dbs_timer(void *data) { int i; down(&dbs_sem); - for (i = 0; i < NR_CPUS; i++) - if (cpu_online(i)) - dbs_check_cpu(i); + for_each_online_cpu(i) + dbs_check_cpu(i); schedule_delayed_work(&dbs_work, - sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate)); + usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); up(&dbs_sem); } @@ -360,7 +358,7 @@ static inline void dbs_timer_init(void) { INIT_WORK(&dbs_work, do_dbs_timer, NULL); schedule_delayed_work(&dbs_work, - sampling_rate_in_HZ(dbs_tuners_ins.sampling_rate)); + usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); return; } -- cgit v1.2.2 From 3310010818aa12145905faf97ffe3742acc842e2 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:44 -0700 Subject: [CPUFREQ] Add warning comment about default governors. This comes up time and time again. Until its fixed, place this comment in the Kconfig which should stem the flow of resubmissions. Signed-off-by: Rob Weryk Signed-off-by: Dave Jones --- drivers/cpufreq/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 95882bb1950e..3617e15567cb 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -46,6 +46,10 @@ config CPU_FREQ_STAT_DETAILS This will show detail CPU frequency translation table in sysfs file system +# Note that it is not currently possible to set the other governors (such as ondemand) +# as the default, since if they fail to initialise, cpufreq will be +# left in an undefined state. + choice prompt "Default CPUFreq governor" default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110 -- cgit v1.2.2 From 7f335d4ef2d50a693fad70b8fa053d0382f4a45c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:46 -0700 Subject: [CPUFREQ] make cpufreq_gov_dbs static This patch makes a needlessly global and EXPORT_SYMBOL'ed struct static. Signed-off-by: Adrian Bunk Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 0bc0bff55d26..84c658822a10 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -459,12 +459,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, return 0; } -struct cpufreq_governor cpufreq_gov_dbs = { +static struct cpufreq_governor cpufreq_gov_dbs = { .name = "ondemand", .governor = cpufreq_governor_dbs, .owner = THIS_MODULE, }; -EXPORT_SYMBOL(cpufreq_gov_dbs); static int __init cpufreq_gov_dbs_init(void) { -- cgit v1.2.2 From b9170836d1aa4ded7cc1ac1cb8fbc7867061c98c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:47 -0700 Subject: [CPUFREQ] Conservative cpufreq governer A new cpufreq module, based on the ondemand one with my additional patches just posted. This one is more suitable for battery environments where its probably more appealing to have the cpu freq gracefully increase and decrease rather than flip between the min and max freq's. N.B. Bruno Ducrot pointed out that the amd64's "do have unacceptable latency between min and max freq transition, due to the step-by-step requirements (200MHz IIRC)"; so AMD64 users would probably benefit from this too. Signed-off-by: Alexander Clouter Signed-off-by: Dave Jones --- drivers/cpufreq/Kconfig | 20 ++ drivers/cpufreq/Makefile | 1 + drivers/cpufreq/cpufreq_conservative.c | 613 +++++++++++++++++++++++++++++++++ 3 files changed, 634 insertions(+) create mode 100644 drivers/cpufreq/cpufreq_conservative.c (limited to 'drivers') diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 3617e15567cb..60c9be99c6d9 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -119,4 +119,24 @@ config CPU_FREQ_GOV_ONDEMAND If in doubt, say N. +config CPU_FREQ_GOV_CONSERVATIVE + tristate "'conservative' cpufreq governor" + depends on CPU_FREQ + help + 'conservative' - this driver is rather similar to the 'ondemand' + governor both in its source code and its purpose, the difference is + its optimisation for better suitability in a battery powered + environment. The frequency is gracefully increased and decreased + rather than jumping to 100% when speed is required. + + If you have a desktop machine then you should really be considering + the 'ondemand' governor instead, however if you are using a laptop, + PDA or even an AMD64 based computer (due to the unacceptable + step-by-step latency issues between the minimum and maximum frequency + transitions in the CPU) you will probably want to use this governor. + + For details, take a look at linux/Documentation/cpu-freq. + + If in doubt, say N. + endif # CPU_FREQ diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index 67b16e5a41a7..71fc3b4173f1 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_PERFORMANCE) += cpufreq_performance.o obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += cpufreq_userspace.o obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND) += cpufreq_ondemand.o +obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE) += cpufreq_conservative.o # CPUfreq cross-arch helpers obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c new file mode 100644 index 000000000000..dd2f5b272a4d --- /dev/null +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -0,0 +1,613 @@ +/* + * drivers/cpufreq/cpufreq_conservative.c + * + * Copyright (C) 2001 Russell King + * (C) 2003 Venkatesh Pallipadi . + * Jun Nakajima + * (C) 2004 Alexander Clouter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * dbs is used in this file as a shortform for demandbased switching + * It helps to keep variable names smaller, simpler + */ + +#define DEF_FREQUENCY_UP_THRESHOLD (80) +#define MIN_FREQUENCY_UP_THRESHOLD (0) +#define MAX_FREQUENCY_UP_THRESHOLD (100) + +#define DEF_FREQUENCY_DOWN_THRESHOLD (20) +#define MIN_FREQUENCY_DOWN_THRESHOLD (0) +#define MAX_FREQUENCY_DOWN_THRESHOLD (100) + +/* + * The polling frequency of this governor depends on the capability of + * the processor. Default polling frequency is 1000 times the transition + * latency of the processor. The governor will work on any processor with + * transition latency <= 10mS, using appropriate sampling + * rate. + * For CPUs with transition latency > 10mS (mostly drivers with CPUFREQ_ETERNAL) + * this governor will not work. + * All times here are in uS. + */ +static unsigned int def_sampling_rate; +#define MIN_SAMPLING_RATE (def_sampling_rate / 2) +#define MAX_SAMPLING_RATE (500 * def_sampling_rate) +#define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (100000) +#define DEF_SAMPLING_DOWN_FACTOR (5) +#define TRANSITION_LATENCY_LIMIT (10 * 1000) + +static void do_dbs_timer(void *data); + +struct cpu_dbs_info_s { + struct cpufreq_policy *cur_policy; + unsigned int prev_cpu_idle_up; + unsigned int prev_cpu_idle_down; + unsigned int enable; +}; +static DEFINE_PER_CPU(struct cpu_dbs_info_s, cpu_dbs_info); + +static unsigned int dbs_enable; /* number of CPUs using this policy */ + +static DECLARE_MUTEX (dbs_sem); +static DECLARE_WORK (dbs_work, do_dbs_timer, NULL); + +struct dbs_tuners { + unsigned int sampling_rate; + unsigned int sampling_down_factor; + unsigned int up_threshold; + unsigned int down_threshold; + unsigned int ignore_nice; + unsigned int freq_step; +}; + +static struct dbs_tuners dbs_tuners_ins = { + .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, + .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, + .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, +}; + +/************************** sysfs interface ************************/ +static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) +{ + return sprintf (buf, "%u\n", MAX_SAMPLING_RATE); +} + +static ssize_t show_sampling_rate_min(struct cpufreq_policy *policy, char *buf) +{ + return sprintf (buf, "%u\n", MIN_SAMPLING_RATE); +} + +#define define_one_ro(_name) \ +static struct freq_attr _name = \ +__ATTR(_name, 0444, show_##_name, NULL) + +define_one_ro(sampling_rate_max); +define_one_ro(sampling_rate_min); + +/* cpufreq_conservative Governor Tunables */ +#define show_one(file_name, object) \ +static ssize_t show_##file_name \ +(struct cpufreq_policy *unused, char *buf) \ +{ \ + return sprintf(buf, "%u\n", dbs_tuners_ins.object); \ +} +show_one(sampling_rate, sampling_rate); +show_one(sampling_down_factor, sampling_down_factor); +show_one(up_threshold, up_threshold); +show_one(down_threshold, down_threshold); +show_one(ignore_nice, ignore_nice); +show_one(freq_step, freq_step); + +static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + ret = sscanf (buf, "%u", &input); + if (ret != 1 ) + return -EINVAL; + + down(&dbs_sem); + dbs_tuners_ins.sampling_down_factor = input; + up(&dbs_sem); + + return count; +} + +static ssize_t store_sampling_rate(struct cpufreq_policy *unused, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + ret = sscanf (buf, "%u", &input); + + down(&dbs_sem); + if (ret != 1 || input > MAX_SAMPLING_RATE || input < MIN_SAMPLING_RATE) { + up(&dbs_sem); + return -EINVAL; + } + + dbs_tuners_ins.sampling_rate = input; + up(&dbs_sem); + + return count; +} + +static ssize_t store_up_threshold(struct cpufreq_policy *unused, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + ret = sscanf (buf, "%u", &input); + + down(&dbs_sem); + if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || + input < MIN_FREQUENCY_UP_THRESHOLD || + input <= dbs_tuners_ins.down_threshold) { + up(&dbs_sem); + return -EINVAL; + } + + dbs_tuners_ins.up_threshold = input; + up(&dbs_sem); + + return count; +} + +static ssize_t store_down_threshold(struct cpufreq_policy *unused, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + ret = sscanf (buf, "%u", &input); + + down(&dbs_sem); + if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || + input < MIN_FREQUENCY_DOWN_THRESHOLD || + input >= dbs_tuners_ins.up_threshold) { + up(&dbs_sem); + return -EINVAL; + } + + dbs_tuners_ins.down_threshold = input; + up(&dbs_sem); + + return count; +} + +static ssize_t store_ignore_nice(struct cpufreq_policy *policy, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + unsigned int j; + + ret = sscanf (buf, "%u", &input); + if ( ret != 1 ) + return -EINVAL; + + if ( input > 1 ) + input = 1; + + down(&dbs_sem); + if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ + up(&dbs_sem); + return count; + } + dbs_tuners_ins.ignore_nice = input; + + /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ + for_each_cpu_mask(j, policy->cpus) { + struct cpu_dbs_info_s *j_dbs_info; + j_dbs_info = &per_cpu(cpu_dbs_info, j); + j_dbs_info->cur_policy = policy; + + j_dbs_info->prev_cpu_idle_up = + kstat_cpu(j).cpustat.idle + + kstat_cpu(j).cpustat.iowait + + ( !dbs_tuners_ins.ignore_nice + ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; + } + up(&dbs_sem); + + return count; +} + +static ssize_t store_freq_step(struct cpufreq_policy *policy, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + ret = sscanf (buf, "%u", &input); + + if ( ret != 1 ) + return -EINVAL; + + if ( input > 100 ) + input = 100; + + /* no need to test here if freq_step is zero as the user might actually + * want this, they would be crazy though :) */ + down(&dbs_sem); + dbs_tuners_ins.freq_step = input; + up(&dbs_sem); + + return count; +} + +#define define_one_rw(_name) \ +static struct freq_attr _name = \ +__ATTR(_name, 0644, show_##_name, store_##_name) + +define_one_rw(sampling_rate); +define_one_rw(sampling_down_factor); +define_one_rw(up_threshold); +define_one_rw(down_threshold); +define_one_rw(ignore_nice); +define_one_rw(freq_step); + +static struct attribute * dbs_attributes[] = { + &sampling_rate_max.attr, + &sampling_rate_min.attr, + &sampling_rate.attr, + &sampling_down_factor.attr, + &up_threshold.attr, + &down_threshold.attr, + &ignore_nice.attr, + &freq_step.attr, + NULL +}; + +static struct attribute_group dbs_attr_group = { + .attrs = dbs_attributes, + .name = "conservative", +}; + +/************************** sysfs end ************************/ + +static void dbs_check_cpu(int cpu) +{ + unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; + unsigned int total_idle_ticks; + unsigned int freq_step; + unsigned int freq_down_sampling_rate; + static int down_skip[NR_CPUS]; + static int requested_freq[NR_CPUS]; + static unsigned short init_flag = 0; + struct cpu_dbs_info_s *this_dbs_info; + struct cpu_dbs_info_s *dbs_info; + + struct cpufreq_policy *policy; + unsigned int j; + + this_dbs_info = &per_cpu(cpu_dbs_info, cpu); + if (!this_dbs_info->enable) + return; + + policy = this_dbs_info->cur_policy; + + if ( init_flag == 0 ) { + for ( /* NULL */; init_flag < NR_CPUS; init_flag++ ) { + dbs_info = &per_cpu(cpu_dbs_info, init_flag); + requested_freq[cpu] = dbs_info->cur_policy->cur; + } + init_flag = 1; + } + + /* + * The default safe range is 20% to 80% + * Every sampling_rate, we check + * - If current idle time is less than 20%, then we try to + * increase frequency + * Every sampling_rate*sampling_down_factor, we check + * - If current idle time is more than 80%, then we try to + * decrease frequency + * + * Any frequency increase takes it to the maximum frequency. + * Frequency reduction happens at minimum steps of + * 5% (default) of max_frequency + */ + + /* Check for frequency increase */ + total_idle_ticks = kstat_cpu(cpu).cpustat.idle + + kstat_cpu(cpu).cpustat.iowait; + /* consider 'nice' tasks as 'idle' time too if required */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(cpu).cpustat.nice; + idle_ticks = total_idle_ticks - + this_dbs_info->prev_cpu_idle_up; + this_dbs_info->prev_cpu_idle_up = total_idle_ticks; + + + for_each_cpu_mask(j, policy->cpus) { + unsigned int tmp_idle_ticks; + struct cpu_dbs_info_s *j_dbs_info; + + if (j == cpu) + continue; + + j_dbs_info = &per_cpu(cpu_dbs_info, j); + /* Check for frequency increase */ + total_idle_ticks = kstat_cpu(j).cpustat.idle + + kstat_cpu(j).cpustat.iowait; + /* consider 'nice' too? */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(j).cpustat.nice; + tmp_idle_ticks = total_idle_ticks - + j_dbs_info->prev_cpu_idle_up; + j_dbs_info->prev_cpu_idle_up = total_idle_ticks; + + if (tmp_idle_ticks < idle_ticks) + idle_ticks = tmp_idle_ticks; + } + + /* Scale idle ticks by 100 and compare with up and down ticks */ + idle_ticks *= 100; + up_idle_ticks = (100 - dbs_tuners_ins.up_threshold) * + usecs_to_jiffies(dbs_tuners_ins.sampling_rate); + + if (idle_ticks < up_idle_ticks) { + /* if we are already at full speed then break out early */ + if (requested_freq[cpu] == policy->max) + return; + + freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; + + /* max freq cannot be less than 100. But who knows.... */ + if (unlikely(freq_step == 0)) + freq_step = 5; + + requested_freq[cpu] += freq_step; + if (requested_freq[cpu] > policy->max) + requested_freq[cpu] = policy->max; + + __cpufreq_driver_target(policy, requested_freq[cpu], + CPUFREQ_RELATION_H); + down_skip[cpu] = 0; + this_dbs_info->prev_cpu_idle_down = total_idle_ticks; + return; + } + + /* Check for frequency decrease */ + down_skip[cpu]++; + if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) + return; + + total_idle_ticks = kstat_cpu(cpu).cpustat.idle + + kstat_cpu(cpu).cpustat.iowait; + /* consider 'nice' too? */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(cpu).cpustat.nice; + idle_ticks = total_idle_ticks - + this_dbs_info->prev_cpu_idle_down; + this_dbs_info->prev_cpu_idle_down = total_idle_ticks; + + for_each_cpu_mask(j, policy->cpus) { + unsigned int tmp_idle_ticks; + struct cpu_dbs_info_s *j_dbs_info; + + if (j == cpu) + continue; + + j_dbs_info = &per_cpu(cpu_dbs_info, j); + /* Check for frequency increase */ + total_idle_ticks = kstat_cpu(j).cpustat.idle + + kstat_cpu(j).cpustat.iowait; + /* consider 'nice' too? */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(j).cpustat.nice; + tmp_idle_ticks = total_idle_ticks - + j_dbs_info->prev_cpu_idle_down; + j_dbs_info->prev_cpu_idle_down = total_idle_ticks; + + if (tmp_idle_ticks < idle_ticks) + idle_ticks = tmp_idle_ticks; + } + + /* Scale idle ticks by 100 and compare with up and down ticks */ + idle_ticks *= 100; + down_skip[cpu] = 0; + + freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * + dbs_tuners_ins.sampling_down_factor; + down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * + usecs_to_jiffies(freq_down_sampling_rate); + + if (idle_ticks > down_idle_ticks ) { + /* if we are already at the lowest speed then break out early + * or if we 'cannot' reduce the speed as the user might want + * freq_step to be zero */ + if (requested_freq[cpu] == policy->min + || dbs_tuners_ins.freq_step == 0) + return; + + freq_step = (dbs_tuners_ins.freq_step * policy->max) / 100; + + /* max freq cannot be less than 100. But who knows.... */ + if (unlikely(freq_step == 0)) + freq_step = 5; + + requested_freq[cpu] -= freq_step; + if (requested_freq[cpu] < policy->min) + requested_freq[cpu] = policy->min; + + __cpufreq_driver_target(policy, + requested_freq[cpu], + CPUFREQ_RELATION_H); + return; + } +} + +static void do_dbs_timer(void *data) +{ + int i; + down(&dbs_sem); + for_each_online_cpu(i) + dbs_check_cpu(i); + schedule_delayed_work(&dbs_work, + usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); + up(&dbs_sem); +} + +static inline void dbs_timer_init(void) +{ + INIT_WORK(&dbs_work, do_dbs_timer, NULL); + schedule_delayed_work(&dbs_work, + usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); + return; +} + +static inline void dbs_timer_exit(void) +{ + cancel_delayed_work(&dbs_work); + return; +} + +static int cpufreq_governor_dbs(struct cpufreq_policy *policy, + unsigned int event) +{ + unsigned int cpu = policy->cpu; + struct cpu_dbs_info_s *this_dbs_info; + unsigned int j; + + this_dbs_info = &per_cpu(cpu_dbs_info, cpu); + + switch (event) { + case CPUFREQ_GOV_START: + if ((!cpu_online(cpu)) || + (!policy->cur)) + return -EINVAL; + + if (policy->cpuinfo.transition_latency > + (TRANSITION_LATENCY_LIMIT * 1000)) + return -EINVAL; + if (this_dbs_info->enable) /* Already enabled */ + break; + + down(&dbs_sem); + for_each_cpu_mask(j, policy->cpus) { + struct cpu_dbs_info_s *j_dbs_info; + j_dbs_info = &per_cpu(cpu_dbs_info, j); + j_dbs_info->cur_policy = policy; + + j_dbs_info->prev_cpu_idle_up = + kstat_cpu(j).cpustat.idle + + kstat_cpu(j).cpustat.iowait + + ( !dbs_tuners_ins.ignore_nice + ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_down + = j_dbs_info->prev_cpu_idle_up; + } + this_dbs_info->enable = 1; + sysfs_create_group(&policy->kobj, &dbs_attr_group); + dbs_enable++; + /* + * Start the timerschedule work, when this governor + * is used for first time + */ + if (dbs_enable == 1) { + unsigned int latency; + /* policy latency is in nS. Convert it to uS first */ + + latency = policy->cpuinfo.transition_latency; + if (latency < 1000) + latency = 1000; + + def_sampling_rate = (latency / 1000) * + DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; + dbs_tuners_ins.sampling_rate = def_sampling_rate; + dbs_tuners_ins.ignore_nice = 0; + dbs_tuners_ins.freq_step = 5; + + dbs_timer_init(); + } + + up(&dbs_sem); + break; + + case CPUFREQ_GOV_STOP: + down(&dbs_sem); + this_dbs_info->enable = 0; + sysfs_remove_group(&policy->kobj, &dbs_attr_group); + dbs_enable--; + /* + * Stop the timerschedule work, when this governor + * is used for first time + */ + if (dbs_enable == 0) + dbs_timer_exit(); + + up(&dbs_sem); + + break; + + case CPUFREQ_GOV_LIMITS: + down(&dbs_sem); + if (policy->max < this_dbs_info->cur_policy->cur) + __cpufreq_driver_target( + this_dbs_info->cur_policy, + policy->max, CPUFREQ_RELATION_H); + else if (policy->min > this_dbs_info->cur_policy->cur) + __cpufreq_driver_target( + this_dbs_info->cur_policy, + policy->min, CPUFREQ_RELATION_L); + up(&dbs_sem); + break; + } + return 0; +} + +static struct cpufreq_governor cpufreq_gov_dbs = { + .name = "conservative", + .governor = cpufreq_governor_dbs, + .owner = THIS_MODULE, +}; + +static int __init cpufreq_gov_dbs_init(void) +{ + return cpufreq_register_governor(&cpufreq_gov_dbs); +} + +static void __exit cpufreq_gov_dbs_exit(void) +{ + /* Make sure that the scheduled work is indeed not running */ + flush_scheduled_work(); + + cpufreq_unregister_governor(&cpufreq_gov_dbs); +} + + +MODULE_AUTHOR ("Alexander Clouter "); +MODULE_DESCRIPTION ("'cpufreq_conservative' - A dynamic cpufreq governor for " + "Low Latency Frequency Transition capable processors " + "optimised for use in a battery environment"); +MODULE_LICENSE ("GPL"); + +module_init(cpufreq_gov_dbs_init); +module_exit(cpufreq_gov_dbs_exit); -- cgit v1.2.2 From 3d5ee9e55d13de28d2fa58d6e13f2e4d3a5f8b1a Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:47 -0700 Subject: [CPUFREQ] Add support to cpufreq_ondemand to ignore 'nice' cpu time Signed-off-by: Alexander Clouter Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 66 +++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 84c658822a10..7d7244314ac9 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -78,6 +78,7 @@ struct dbs_tuners { unsigned int sampling_down_factor; unsigned int up_threshold; unsigned int down_threshold; + unsigned int ignore_nice; }; static struct dbs_tuners dbs_tuners_ins = { @@ -115,6 +116,7 @@ show_one(sampling_rate, sampling_rate); show_one(sampling_down_factor, sampling_down_factor); show_one(up_threshold, up_threshold); show_one(down_threshold, down_threshold); +show_one(ignore_nice, ignore_nice); static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, const char *buf, size_t count) @@ -193,6 +195,46 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused, return count; } +static ssize_t store_ignore_nice(struct cpufreq_policy *policy, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + unsigned int j; + + ret = sscanf (buf, "%u", &input); + if ( ret != 1 ) + return -EINVAL; + + if ( input > 1 ) + input = 1; + + down(&dbs_sem); + if ( input == dbs_tuners_ins.ignore_nice ) { /* nothing to do */ + up(&dbs_sem); + return count; + } + dbs_tuners_ins.ignore_nice = input; + + /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ + for_each_cpu_mask(j, policy->cpus) { + struct cpu_dbs_info_s *j_dbs_info; + j_dbs_info = &per_cpu(cpu_dbs_info, j); + j_dbs_info->cur_policy = policy; + + j_dbs_info->prev_cpu_idle_up = + kstat_cpu(j).cpustat.idle + + kstat_cpu(j).cpustat.iowait + + ( !dbs_tuners_ins.ignore_nice + ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; + } + up(&dbs_sem); + + return count; +} + #define define_one_rw(_name) \ static struct freq_attr _name = \ __ATTR(_name, 0644, show_##_name, store_##_name) @@ -201,6 +243,7 @@ define_one_rw(sampling_rate); define_one_rw(sampling_down_factor); define_one_rw(up_threshold); define_one_rw(down_threshold); +define_one_rw(ignore_nice); static struct attribute * dbs_attributes[] = { &sampling_rate_max.attr, @@ -209,6 +252,7 @@ static struct attribute * dbs_attributes[] = { &sampling_down_factor.attr, &up_threshold.attr, &down_threshold.attr, + &ignore_nice.attr, NULL }; @@ -253,6 +297,9 @@ static void dbs_check_cpu(int cpu) /* Check for frequency increase */ total_idle_ticks = kstat_cpu(cpu).cpustat.idle + kstat_cpu(cpu).cpustat.iowait; + /* consider 'nice' tasks as 'idle' time too if required */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(cpu).cpustat.nice; idle_ticks = total_idle_ticks - this_dbs_info->prev_cpu_idle_up; this_dbs_info->prev_cpu_idle_up = total_idle_ticks; @@ -269,6 +316,9 @@ static void dbs_check_cpu(int cpu) /* Check for frequency increase */ total_idle_ticks = kstat_cpu(j).cpustat.idle + kstat_cpu(j).cpustat.iowait; + /* consider 'nice' too? */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(j).cpustat.nice; tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_up; j_dbs_info->prev_cpu_idle_up = total_idle_ticks; @@ -297,6 +347,9 @@ static void dbs_check_cpu(int cpu) total_idle_ticks = kstat_cpu(cpu).cpustat.idle + kstat_cpu(cpu).cpustat.iowait; + /* consider 'nice' too? */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(cpu).cpustat.nice; idle_ticks = total_idle_ticks - this_dbs_info->prev_cpu_idle_down; this_dbs_info->prev_cpu_idle_down = total_idle_ticks; @@ -312,6 +365,9 @@ static void dbs_check_cpu(int cpu) /* Check for frequency increase */ total_idle_ticks = kstat_cpu(j).cpustat.idle + kstat_cpu(j).cpustat.iowait; + /* consider 'nice' too? */ + if (dbs_tuners_ins.ignore_nice == 0) + total_idle_ticks += kstat_cpu(j).cpustat.nice; tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_down; j_dbs_info->prev_cpu_idle_down = total_idle_ticks; @@ -397,10 +453,11 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, j_dbs_info->prev_cpu_idle_up = kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait; - j_dbs_info->prev_cpu_idle_down = - kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait; + kstat_cpu(j).cpustat.iowait + + ( !dbs_tuners_ins.ignore_nice + ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_down + = j_dbs_info->prev_cpu_idle_up; } this_dbs_info->enable = 1; sysfs_create_group(&policy->kobj, &dbs_attr_group); @@ -420,6 +477,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, def_sampling_rate = (latency / 1000) * DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; dbs_tuners_ins.sampling_rate = def_sampling_rate; + dbs_tuners_ins.ignore_nice = 0; dbs_timer_init(); } -- cgit v1.2.2 From c11420a616039e2181e4ecbffb4d125d39e6877d Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:48 -0700 Subject: [CPUFREQ] Prevents un-necessary cpufreq changes if we are already at min/max Signed-off-by: Alexander Clouter Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 7d7244314ac9..6dc83808e590 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -333,6 +333,10 @@ static void dbs_check_cpu(int cpu) usecs_to_jiffies(dbs_tuners_ins.sampling_rate); if (idle_ticks < up_idle_ticks) { + /* if we are already at full speed then break out early */ + if (policy->cur == policy->max) + return; + __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); down_skip[cpu] = 0; @@ -386,6 +390,10 @@ static void dbs_check_cpu(int cpu) usecs_to_jiffies(freq_down_sampling_rate); if (idle_ticks > down_idle_ticks ) { + /* if we are already at the lowest speed then break out early */ + if (policy->cur == policy->min) + return; + freq_down_step = (5 * policy->max) / 100; /* max freq cannot be less than 100. But who knows.... */ -- cgit v1.2.2 From 1206aaac285904e3e3995eecbf4129b6555a8973 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:48 -0700 Subject: [CPUFREQ] Allow ondemand stepping to be changed by user. Adds support so that the cpufreq change stepping is no longer fixed at 5% and can be changed dynamically by the user Signed-off-by: Alexander Clouter Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 42 ++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 6dc83808e590..056591612467 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -79,6 +79,7 @@ struct dbs_tuners { unsigned int up_threshold; unsigned int down_threshold; unsigned int ignore_nice; + unsigned int freq_step; }; static struct dbs_tuners dbs_tuners_ins = { @@ -117,6 +118,7 @@ show_one(sampling_down_factor, sampling_down_factor); show_one(up_threshold, up_threshold); show_one(down_threshold, down_threshold); show_one(ignore_nice, ignore_nice); +show_one(freq_step, freq_step); static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, const char *buf, size_t count) @@ -235,6 +237,29 @@ static ssize_t store_ignore_nice(struct cpufreq_policy *policy, return count; } +static ssize_t store_freq_step(struct cpufreq_policy *policy, + const char *buf, size_t count) +{ + unsigned int input; + int ret; + + ret = sscanf (buf, "%u", &input); + + if ( ret != 1 ) + return -EINVAL; + + if ( input > 100 ) + input = 100; + + /* no need to test here if freq_step is zero as the user might actually + * want this, they would be crazy though :) */ + down(&dbs_sem); + dbs_tuners_ins.freq_step = input; + up(&dbs_sem); + + return count; +} + #define define_one_rw(_name) \ static struct freq_attr _name = \ __ATTR(_name, 0644, show_##_name, store_##_name) @@ -244,6 +269,7 @@ define_one_rw(sampling_down_factor); define_one_rw(up_threshold); define_one_rw(down_threshold); define_one_rw(ignore_nice); +define_one_rw(freq_step); static struct attribute * dbs_attributes[] = { &sampling_rate_max.attr, @@ -253,6 +279,7 @@ static struct attribute * dbs_attributes[] = { &up_threshold.attr, &down_threshold.attr, &ignore_nice.attr, + &freq_step.attr, NULL }; @@ -291,7 +318,7 @@ static void dbs_check_cpu(int cpu) * * Any frequency increase takes it to the maximum frequency. * Frequency reduction happens at minimum steps of - * 5% of max_frequency + * 5% (default) of max_frequency */ /* Check for frequency increase */ @@ -390,18 +417,20 @@ static void dbs_check_cpu(int cpu) usecs_to_jiffies(freq_down_sampling_rate); if (idle_ticks > down_idle_ticks ) { - /* if we are already at the lowest speed then break out early */ - if (policy->cur == policy->min) + /* if we are already at the lowest speed then break out early + * or if we 'cannot' reduce the speed as the user might want + * freq_step to be zero */ + if (policy->cur == policy->min || dbs_tuners_ins.freq_step == 0) return; - - freq_down_step = (5 * policy->max) / 100; + + freq_down_step = (dbs_tuners_ins.freq_step * policy->max) / 100; /* max freq cannot be less than 100. But who knows.... */ if (unlikely(freq_down_step == 0)) freq_down_step = 5; __cpufreq_driver_target(policy, - policy->cur - freq_down_step, + policy->cur - freq_down_step, CPUFREQ_RELATION_H); return; } @@ -486,6 +515,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; dbs_tuners_ins.sampling_rate = def_sampling_rate; dbs_tuners_ins.ignore_nice = 0; + dbs_tuners_ins.freq_step = 5; dbs_timer_init(); } -- cgit v1.2.2 From dac1c1a56279b4545a822ec7bc770003c233e546 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:49 -0700 Subject: [CPUFREQ] ondemand,conservative minor bug-fix and cleanup [PATCH] [1/5] ondemand,conservative minor bug-fix and cleanup Attached patch fixes some minor issues with Alexander's patch and related cleanup in both ondemand and conservative governor. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_conservative.c | 53 +++++++++++-------------------- drivers/cpufreq/cpufreq_ondemand.c | 58 ++++++++++++---------------------- 2 files changed, 38 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index dd2f5b272a4d..3082a3fa5ec4 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -89,6 +89,15 @@ static struct dbs_tuners dbs_tuners_ins = { .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, }; +static inline unsigned int get_cpu_idle_time(unsigned int cpu) +{ + return kstat_cpu(cpu).cpustat.idle + + kstat_cpu(cpu).cpustat.iowait + + ( !dbs_tuners_ins.ignore_nice ? + kstat_cpu(cpu).cpustat.nice : + 0); +} + /************************** sysfs interface ************************/ static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) { @@ -221,16 +230,10 @@ static ssize_t store_ignore_nice(struct cpufreq_policy *policy, dbs_tuners_ins.ignore_nice = input; /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ - for_each_cpu_mask(j, policy->cpus) { + for_each_online_cpu(j) { struct cpu_dbs_info_s *j_dbs_info; j_dbs_info = &per_cpu(cpu_dbs_info, j); - j_dbs_info->cur_policy = policy; - - j_dbs_info->prev_cpu_idle_up = - kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait + - ( !dbs_tuners_ins.ignore_nice - ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; } up(&dbs_sem); @@ -335,11 +338,7 @@ static void dbs_check_cpu(int cpu) */ /* Check for frequency increase */ - total_idle_ticks = kstat_cpu(cpu).cpustat.idle + - kstat_cpu(cpu).cpustat.iowait; - /* consider 'nice' tasks as 'idle' time too if required */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(cpu).cpustat.nice; + total_idle_ticks = get_cpu_idle_time(cpu); idle_ticks = total_idle_ticks - this_dbs_info->prev_cpu_idle_up; this_dbs_info->prev_cpu_idle_up = total_idle_ticks; @@ -354,11 +353,7 @@ static void dbs_check_cpu(int cpu) j_dbs_info = &per_cpu(cpu_dbs_info, j); /* Check for frequency increase */ - total_idle_ticks = kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait; - /* consider 'nice' too? */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(j).cpustat.nice; + total_idle_ticks = get_cpu_idle_time(j); tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_up; j_dbs_info->prev_cpu_idle_up = total_idle_ticks; @@ -373,6 +368,8 @@ static void dbs_check_cpu(int cpu) usecs_to_jiffies(dbs_tuners_ins.sampling_rate); if (idle_ticks < up_idle_ticks) { + down_skip[cpu] = 0; + this_dbs_info->prev_cpu_idle_down = total_idle_ticks; /* if we are already at full speed then break out early */ if (requested_freq[cpu] == policy->max) return; @@ -389,8 +386,6 @@ static void dbs_check_cpu(int cpu) __cpufreq_driver_target(policy, requested_freq[cpu], CPUFREQ_RELATION_H); - down_skip[cpu] = 0; - this_dbs_info->prev_cpu_idle_down = total_idle_ticks; return; } @@ -399,11 +394,7 @@ static void dbs_check_cpu(int cpu) if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) return; - total_idle_ticks = kstat_cpu(cpu).cpustat.idle + - kstat_cpu(cpu).cpustat.iowait; - /* consider 'nice' too? */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(cpu).cpustat.nice; + total_idle_ticks = this_dbs_info->prev_cpu_idle_up; idle_ticks = total_idle_ticks - this_dbs_info->prev_cpu_idle_down; this_dbs_info->prev_cpu_idle_down = total_idle_ticks; @@ -417,11 +408,7 @@ static void dbs_check_cpu(int cpu) j_dbs_info = &per_cpu(cpu_dbs_info, j); /* Check for frequency increase */ - total_idle_ticks = kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait; - /* consider 'nice' too? */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(j).cpustat.nice; + total_idle_ticks = j_dbs_info->prev_cpu_idle_up; tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_down; j_dbs_info->prev_cpu_idle_down = total_idle_ticks; @@ -516,11 +503,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, j_dbs_info = &per_cpu(cpu_dbs_info, j); j_dbs_info->cur_policy = policy; - j_dbs_info->prev_cpu_idle_up = - kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait + - ( !dbs_tuners_ins.ignore_nice - ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; } diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 056591612467..26cf54b11ba6 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -88,6 +88,15 @@ static struct dbs_tuners dbs_tuners_ins = { .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, }; +static inline unsigned int get_cpu_idle_time(unsigned int cpu) +{ + return kstat_cpu(cpu).cpustat.idle + + kstat_cpu(cpu).cpustat.iowait + + ( !dbs_tuners_ins.ignore_nice ? + kstat_cpu(cpu).cpustat.nice : + 0); +} + /************************** sysfs interface ************************/ static ssize_t show_sampling_rate_max(struct cpufreq_policy *policy, char *buf) { @@ -220,16 +229,10 @@ static ssize_t store_ignore_nice(struct cpufreq_policy *policy, dbs_tuners_ins.ignore_nice = input; /* we need to re-evaluate prev_cpu_idle_up and prev_cpu_idle_down */ - for_each_cpu_mask(j, policy->cpus) { + for_each_online_cpu(j) { struct cpu_dbs_info_s *j_dbs_info; j_dbs_info = &per_cpu(cpu_dbs_info, j); - j_dbs_info->cur_policy = policy; - - j_dbs_info->prev_cpu_idle_up = - kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait + - ( !dbs_tuners_ins.ignore_nice - ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; } up(&dbs_sem); @@ -322,15 +325,10 @@ static void dbs_check_cpu(int cpu) */ /* Check for frequency increase */ - total_idle_ticks = kstat_cpu(cpu).cpustat.idle + - kstat_cpu(cpu).cpustat.iowait; - /* consider 'nice' tasks as 'idle' time too if required */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(cpu).cpustat.nice; + total_idle_ticks = get_cpu_idle_time(cpu); idle_ticks = total_idle_ticks - this_dbs_info->prev_cpu_idle_up; this_dbs_info->prev_cpu_idle_up = total_idle_ticks; - for_each_cpu_mask(j, policy->cpus) { unsigned int tmp_idle_ticks; @@ -341,11 +339,7 @@ static void dbs_check_cpu(int cpu) j_dbs_info = &per_cpu(cpu_dbs_info, j); /* Check for frequency increase */ - total_idle_ticks = kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait; - /* consider 'nice' too? */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(j).cpustat.nice; + total_idle_ticks = get_cpu_idle_time(j); tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_up; j_dbs_info->prev_cpu_idle_up = total_idle_ticks; @@ -360,14 +354,14 @@ static void dbs_check_cpu(int cpu) usecs_to_jiffies(dbs_tuners_ins.sampling_rate); if (idle_ticks < up_idle_ticks) { + down_skip[cpu] = 0; + this_dbs_info->prev_cpu_idle_down = total_idle_ticks; /* if we are already at full speed then break out early */ if (policy->cur == policy->max) return; __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H); - down_skip[cpu] = 0; - this_dbs_info->prev_cpu_idle_down = total_idle_ticks; return; } @@ -376,11 +370,7 @@ static void dbs_check_cpu(int cpu) if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) return; - total_idle_ticks = kstat_cpu(cpu).cpustat.idle + - kstat_cpu(cpu).cpustat.iowait; - /* consider 'nice' too? */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(cpu).cpustat.nice; + total_idle_ticks = this_dbs_info->prev_cpu_idle_up; idle_ticks = total_idle_ticks - this_dbs_info->prev_cpu_idle_down; this_dbs_info->prev_cpu_idle_down = total_idle_ticks; @@ -393,12 +383,8 @@ static void dbs_check_cpu(int cpu) continue; j_dbs_info = &per_cpu(cpu_dbs_info, j); - /* Check for frequency increase */ - total_idle_ticks = kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait; - /* consider 'nice' too? */ - if (dbs_tuners_ins.ignore_nice == 0) - total_idle_ticks += kstat_cpu(j).cpustat.nice; + /* Check for frequency decrease */ + total_idle_ticks = j_dbs_info->prev_cpu_idle_up; tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_down; j_dbs_info->prev_cpu_idle_down = total_idle_ticks; @@ -414,7 +400,7 @@ static void dbs_check_cpu(int cpu) freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * dbs_tuners_ins.sampling_down_factor; down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * - usecs_to_jiffies(freq_down_sampling_rate); + usecs_to_jiffies(freq_down_sampling_rate); if (idle_ticks > down_idle_ticks ) { /* if we are already at the lowest speed then break out early @@ -488,11 +474,7 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, j_dbs_info = &per_cpu(cpu_dbs_info, j); j_dbs_info->cur_policy = policy; - j_dbs_info->prev_cpu_idle_up = - kstat_cpu(j).cpustat.idle + - kstat_cpu(j).cpustat.iowait + - ( !dbs_tuners_ins.ignore_nice - ? kstat_cpu(j).cpustat.nice : 0 ); + j_dbs_info->prev_cpu_idle_up = get_cpu_idle_time(j); j_dbs_info->prev_cpu_idle_down = j_dbs_info->prev_cpu_idle_up; } -- cgit v1.2.2 From 790d76fa979f55bfc49a6901bb911778949b582d Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:49 -0700 Subject: [CPUFREQ] ondemand,conservative governor store the idle ticks for all cpus [PATCH] [2/5] ondemand,conservative governor store the idle ticks for all cpus Ondemand, conservative governor did not store prev_cpu_idle_up into prev_cpu_idle_down for other CPUs than the current CPU. Signed-off-by: Eric Piel Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_conservative.c | 8 +++++++- drivers/cpufreq/cpufreq_ondemand.c | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 3082a3fa5ec4..c503ec14765f 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -369,7 +369,13 @@ static void dbs_check_cpu(int cpu) if (idle_ticks < up_idle_ticks) { down_skip[cpu] = 0; - this_dbs_info->prev_cpu_idle_down = total_idle_ticks; + for_each_cpu_mask(j, policy->cpus) { + struct cpu_dbs_info_s *j_dbs_info; + + j_dbs_info = &per_cpu(cpu_dbs_info, j); + j_dbs_info->prev_cpu_idle_down = + j_dbs_info->prev_cpu_idle_up; + } /* if we are already at full speed then break out early */ if (requested_freq[cpu] == policy->max) return; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 26cf54b11ba6..f239545ac1b8 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -355,7 +355,13 @@ static void dbs_check_cpu(int cpu) if (idle_ticks < up_idle_ticks) { down_skip[cpu] = 0; - this_dbs_info->prev_cpu_idle_down = total_idle_ticks; + for_each_cpu_mask(j, policy->cpus) { + struct cpu_dbs_info_s *j_dbs_info; + + j_dbs_info = &per_cpu(cpu_dbs_info, j); + j_dbs_info->prev_cpu_idle_down = + j_dbs_info->prev_cpu_idle_up; + } /* if we are already at full speed then break out early */ if (policy->cur == policy->max) return; -- cgit v1.2.2 From 9c7d269b9b05440dd0fe92d96f4e5d7e73dd7238 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:49 -0700 Subject: [CPUFREQ] ondemand,conservative governor idle_tick clean-up [PATCH] [3/5] ondemand,conservative governor idle_tick clean-up Ondemand and conservative governor clean-up, it factorises the idle ticks measurement. Signed-off-by: Eric Piel Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_conservative.c | 26 +++++--------------------- drivers/cpufreq/cpufreq_ondemand.c | 26 +++++--------------------- 2 files changed, 10 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index c503ec14765f..e1df376e709e 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -297,7 +297,6 @@ static struct attribute_group dbs_attr_group = { static void dbs_check_cpu(int cpu) { unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; - unsigned int total_idle_ticks; unsigned int freq_step; unsigned int freq_down_sampling_rate; static int down_skip[NR_CPUS]; @@ -338,19 +337,12 @@ static void dbs_check_cpu(int cpu) */ /* Check for frequency increase */ - total_idle_ticks = get_cpu_idle_time(cpu); - idle_ticks = total_idle_ticks - - this_dbs_info->prev_cpu_idle_up; - this_dbs_info->prev_cpu_idle_up = total_idle_ticks; - + idle_ticks = UINT_MAX; for_each_cpu_mask(j, policy->cpus) { - unsigned int tmp_idle_ticks; + unsigned int tmp_idle_ticks, total_idle_ticks; struct cpu_dbs_info_s *j_dbs_info; - if (j == cpu) - continue; - j_dbs_info = &per_cpu(cpu_dbs_info, j); /* Check for frequency increase */ total_idle_ticks = get_cpu_idle_time(j); @@ -400,20 +392,12 @@ static void dbs_check_cpu(int cpu) if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) return; - total_idle_ticks = this_dbs_info->prev_cpu_idle_up; - idle_ticks = total_idle_ticks - - this_dbs_info->prev_cpu_idle_down; - this_dbs_info->prev_cpu_idle_down = total_idle_ticks; - + idle_ticks = UINT_MAX; for_each_cpu_mask(j, policy->cpus) { - unsigned int tmp_idle_ticks; + unsigned int tmp_idle_ticks, total_idle_ticks; struct cpu_dbs_info_s *j_dbs_info; - if (j == cpu) - continue; - j_dbs_info = &per_cpu(cpu_dbs_info, j); - /* Check for frequency increase */ total_idle_ticks = j_dbs_info->prev_cpu_idle_up; tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_down; @@ -432,7 +416,7 @@ static void dbs_check_cpu(int cpu) down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * usecs_to_jiffies(freq_down_sampling_rate); - if (idle_ticks > down_idle_ticks ) { + if (idle_ticks > down_idle_ticks) { /* if we are already at the lowest speed then break out early * or if we 'cannot' reduce the speed as the user might want * freq_step to be zero */ diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index f239545ac1b8..0482bd49aba8 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -296,7 +296,6 @@ static struct attribute_group dbs_attr_group = { static void dbs_check_cpu(int cpu) { unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; - unsigned int total_idle_ticks; unsigned int freq_down_step; unsigned int freq_down_sampling_rate; static int down_skip[NR_CPUS]; @@ -325,20 +324,12 @@ static void dbs_check_cpu(int cpu) */ /* Check for frequency increase */ - total_idle_ticks = get_cpu_idle_time(cpu); - idle_ticks = total_idle_ticks - - this_dbs_info->prev_cpu_idle_up; - this_dbs_info->prev_cpu_idle_up = total_idle_ticks; - + idle_ticks = UINT_MAX; for_each_cpu_mask(j, policy->cpus) { - unsigned int tmp_idle_ticks; + unsigned int tmp_idle_ticks, total_idle_ticks; struct cpu_dbs_info_s *j_dbs_info; - if (j == cpu) - continue; - j_dbs_info = &per_cpu(cpu_dbs_info, j); - /* Check for frequency increase */ total_idle_ticks = get_cpu_idle_time(j); tmp_idle_ticks = total_idle_ticks - j_dbs_info->prev_cpu_idle_up; @@ -376,18 +367,11 @@ static void dbs_check_cpu(int cpu) if (down_skip[cpu] < dbs_tuners_ins.sampling_down_factor) return; - total_idle_ticks = this_dbs_info->prev_cpu_idle_up; - idle_ticks = total_idle_ticks - - this_dbs_info->prev_cpu_idle_down; - this_dbs_info->prev_cpu_idle_down = total_idle_ticks; - + idle_ticks = UINT_MAX; for_each_cpu_mask(j, policy->cpus) { - unsigned int tmp_idle_ticks; + unsigned int tmp_idle_ticks, total_idle_ticks; struct cpu_dbs_info_s *j_dbs_info; - if (j == cpu) - continue; - j_dbs_info = &per_cpu(cpu_dbs_info, j); /* Check for frequency decrease */ total_idle_ticks = j_dbs_info->prev_cpu_idle_up; @@ -408,7 +392,7 @@ static void dbs_check_cpu(int cpu) down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * usecs_to_jiffies(freq_down_sampling_rate); - if (idle_ticks > down_idle_ticks ) { + if (idle_ticks > down_idle_ticks) { /* if we are already at the lowest speed then break out early * or if we 'cannot' reduce the speed as the user might want * freq_step to be zero */ -- cgit v1.2.2 From c29f1403098135bdef75b190a5037db514701031 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:50 -0700 Subject: [CPUFREQ] ondemand governor automatic downscaling [PATCH] [4/5] ondemand governor automatic downscaling Here is a change of policy for the ondemand governor. The modification concerns the frequency downscaling. Instead of decreasing to a lower frequency when the CPU usage is under 20%, this new policy automatically scales to the optimal frequency. The optimal frequency being the lowest frequency which provides enough power to not trigger the upscaling policy. Signed-off-by: Eric Piel Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 117 ++++++++----------------------------- 1 file changed, 25 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 0482bd49aba8..8bc38ab96400 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -34,13 +34,9 @@ */ #define DEF_FREQUENCY_UP_THRESHOLD (80) -#define MIN_FREQUENCY_UP_THRESHOLD (0) +#define MIN_FREQUENCY_UP_THRESHOLD (11) #define MAX_FREQUENCY_UP_THRESHOLD (100) -#define DEF_FREQUENCY_DOWN_THRESHOLD (20) -#define MIN_FREQUENCY_DOWN_THRESHOLD (0) -#define MAX_FREQUENCY_DOWN_THRESHOLD (100) - /* * The polling frequency of this governor depends on the capability of * the processor. Default polling frequency is 1000 times the transition @@ -77,14 +73,11 @@ struct dbs_tuners { unsigned int sampling_rate; unsigned int sampling_down_factor; unsigned int up_threshold; - unsigned int down_threshold; unsigned int ignore_nice; - unsigned int freq_step; }; static struct dbs_tuners dbs_tuners_ins = { .up_threshold = DEF_FREQUENCY_UP_THRESHOLD, - .down_threshold = DEF_FREQUENCY_DOWN_THRESHOLD, .sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR, }; @@ -125,9 +118,7 @@ static ssize_t show_##file_name \ show_one(sampling_rate, sampling_rate); show_one(sampling_down_factor, sampling_down_factor); show_one(up_threshold, up_threshold); -show_one(down_threshold, down_threshold); show_one(ignore_nice, ignore_nice); -show_one(freq_step, freq_step); static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, const char *buf, size_t count) @@ -173,8 +164,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, down(&dbs_sem); if (ret != 1 || input > MAX_FREQUENCY_UP_THRESHOLD || - input < MIN_FREQUENCY_UP_THRESHOLD || - input <= dbs_tuners_ins.down_threshold) { + input < MIN_FREQUENCY_UP_THRESHOLD) { up(&dbs_sem); return -EINVAL; } @@ -185,27 +175,6 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, return count; } -static ssize_t store_down_threshold(struct cpufreq_policy *unused, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - ret = sscanf (buf, "%u", &input); - - down(&dbs_sem); - if (ret != 1 || input > MAX_FREQUENCY_DOWN_THRESHOLD || - input < MIN_FREQUENCY_DOWN_THRESHOLD || - input >= dbs_tuners_ins.up_threshold) { - up(&dbs_sem); - return -EINVAL; - } - - dbs_tuners_ins.down_threshold = input; - up(&dbs_sem); - - return count; -} - static ssize_t store_ignore_nice(struct cpufreq_policy *policy, const char *buf, size_t count) { @@ -240,29 +209,6 @@ static ssize_t store_ignore_nice(struct cpufreq_policy *policy, return count; } -static ssize_t store_freq_step(struct cpufreq_policy *policy, - const char *buf, size_t count) -{ - unsigned int input; - int ret; - - ret = sscanf (buf, "%u", &input); - - if ( ret != 1 ) - return -EINVAL; - - if ( input > 100 ) - input = 100; - - /* no need to test here if freq_step is zero as the user might actually - * want this, they would be crazy though :) */ - down(&dbs_sem); - dbs_tuners_ins.freq_step = input; - up(&dbs_sem); - - return count; -} - #define define_one_rw(_name) \ static struct freq_attr _name = \ __ATTR(_name, 0644, show_##_name, store_##_name) @@ -270,9 +216,7 @@ __ATTR(_name, 0644, show_##_name, store_##_name) define_one_rw(sampling_rate); define_one_rw(sampling_down_factor); define_one_rw(up_threshold); -define_one_rw(down_threshold); define_one_rw(ignore_nice); -define_one_rw(freq_step); static struct attribute * dbs_attributes[] = { &sampling_rate_max.attr, @@ -280,9 +224,7 @@ static struct attribute * dbs_attributes[] = { &sampling_rate.attr, &sampling_down_factor.attr, &up_threshold.attr, - &down_threshold.attr, &ignore_nice.attr, - &freq_step.attr, NULL }; @@ -295,8 +237,8 @@ static struct attribute_group dbs_attr_group = { static void dbs_check_cpu(int cpu) { - unsigned int idle_ticks, up_idle_ticks, down_idle_ticks; - unsigned int freq_down_step; + unsigned int idle_ticks, up_idle_ticks, total_ticks; + unsigned int freq_next; unsigned int freq_down_sampling_rate; static int down_skip[NR_CPUS]; struct cpu_dbs_info_s *this_dbs_info; @@ -310,17 +252,15 @@ static void dbs_check_cpu(int cpu) policy = this_dbs_info->cur_policy; /* - * The default safe range is 20% to 80% - * Every sampling_rate, we check - * - If current idle time is less than 20%, then we try to - * increase frequency - * Every sampling_rate*sampling_down_factor, we check - * - If current idle time is more than 80%, then we try to - * decrease frequency + * Every sampling_rate, we check, if current idle time is less + * than 20% (default), then we try to increase frequency + * Every sampling_rate*sampling_down_factor, we look for a the lowest + * frequency which can sustain the load while keeping idle time over + * 30%. If such a frequency exist, we try to decrease to this frequency. * * Any frequency increase takes it to the maximum frequency. * Frequency reduction happens at minimum steps of - * 5% (default) of max_frequency + * 5% (default) of current frequency */ /* Check for frequency increase */ @@ -383,33 +323,27 @@ static void dbs_check_cpu(int cpu) idle_ticks = tmp_idle_ticks; } - /* Scale idle ticks by 100 and compare with up and down ticks */ - idle_ticks *= 100; down_skip[cpu] = 0; + /* if we cannot reduce the frequency anymore, break out early */ + if (policy->cur == policy->min) + return; + /* Compute how many ticks there are between two measurements */ freq_down_sampling_rate = dbs_tuners_ins.sampling_rate * dbs_tuners_ins.sampling_down_factor; - down_idle_ticks = (100 - dbs_tuners_ins.down_threshold) * - usecs_to_jiffies(freq_down_sampling_rate); - - if (idle_ticks > down_idle_ticks) { - /* if we are already at the lowest speed then break out early - * or if we 'cannot' reduce the speed as the user might want - * freq_step to be zero */ - if (policy->cur == policy->min || dbs_tuners_ins.freq_step == 0) - return; + total_ticks = usecs_to_jiffies(freq_down_sampling_rate); - freq_down_step = (dbs_tuners_ins.freq_step * policy->max) / 100; - - /* max freq cannot be less than 100. But who knows.... */ - if (unlikely(freq_down_step == 0)) - freq_down_step = 5; + /* + * The optimal frequency is the frequency that is the lowest that + * can support the current CPU usage without triggering the up + * policy. To be safe, we focus 10 points under the threshold. + */ + freq_next = ((total_ticks - idle_ticks) * 100) / total_ticks; + freq_next = (freq_next * policy->cur) / + (dbs_tuners_ins.up_threshold - 10); - __cpufreq_driver_target(policy, - policy->cur - freq_down_step, - CPUFREQ_RELATION_H); - return; - } + if (freq_next <= ((policy->cur * 95) / 100)) + __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); } static void do_dbs_timer(void *data) @@ -487,7 +421,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, DEF_SAMPLING_RATE_LATENCY_MULTIPLIER; dbs_tuners_ins.sampling_rate = def_sampling_rate; dbs_tuners_ins.ignore_nice = 0; - dbs_tuners_ins.freq_step = 5; dbs_timer_init(); } -- cgit v1.2.2 From e131832ca7d3a3e5f9c7624bb310a7747dc2b57c Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 31 May 2005 19:03:50 -0700 Subject: [CPUFREQ] ondemand governor default sampling downfactor as 1 [PATCH] [5/5] ondemand governor default sampling downfactor as 1 Make default sampling downfactor 1. This works better with earlier auto downscaling change in ondemand governor. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_ondemand.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 8bc38ab96400..c1fc9c62bb51 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -51,7 +51,8 @@ static unsigned int def_sampling_rate; #define MIN_SAMPLING_RATE (def_sampling_rate / 2) #define MAX_SAMPLING_RATE (500 * def_sampling_rate) #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER (1000) -#define DEF_SAMPLING_DOWN_FACTOR (10) +#define DEF_SAMPLING_DOWN_FACTOR (1) +#define MAX_SAMPLING_DOWN_FACTOR (10) #define TRANSITION_LATENCY_LIMIT (10 * 1000) static void do_dbs_timer(void *data); @@ -129,6 +130,9 @@ static ssize_t store_sampling_down_factor(struct cpufreq_policy *unused, if (ret != 1 ) return -EINVAL; + if (input > MAX_SAMPLING_DOWN_FACTOR || input < 1) + return -EINVAL; + down(&dbs_sem); dbs_tuners_ins.sampling_down_factor = input; up(&dbs_sem); -- cgit v1.2.2 From 58f1df25403988b73d7129fcd2c4d4c24017f1af Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Wed, 25 May 2005 14:46:50 -0700 Subject: [PATCH] cpufreq-stats driver updates Changes to the cpufreq stats driver: * Changes the way P-state transition table looks in /sysfs providing more clear output * Changes the time unit in the output from HZ to clock_t Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- drivers/cpufreq/cpufreq_stats.c | 47 ++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 2084593937c6..741b6b191e6a 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -19,6 +19,7 @@ #include #include #include +#include static spinlock_t cpufreq_stats_lock; @@ -29,20 +30,14 @@ static struct freq_attr _attr_##_name = {\ .show = _show,\ }; -static unsigned long -delta_time(unsigned long old, unsigned long new) -{ - return (old > new) ? (old - new): (new + ~old + 1); -} - struct cpufreq_stats { unsigned int cpu; unsigned int total_trans; - unsigned long long last_time; + unsigned long long last_time; unsigned int max_state; unsigned int state_num; unsigned int last_index; - unsigned long long *time_in_state; + cputime64_t *time_in_state; unsigned int *freq_table; #ifdef CONFIG_CPU_FREQ_STAT_DETAILS unsigned int *trans_table; @@ -60,12 +55,16 @@ static int cpufreq_stats_update (unsigned int cpu) { struct cpufreq_stats *stat; + unsigned long long cur_time; + + cur_time = get_jiffies_64(); spin_lock(&cpufreq_stats_lock); stat = cpufreq_stats_table[cpu]; if (stat->time_in_state) - stat->time_in_state[stat->last_index] += - delta_time(stat->last_time, jiffies); - stat->last_time = jiffies; + stat->time_in_state[stat->last_index] = + cputime64_add(stat->time_in_state[stat->last_index], + cputime_sub(cur_time, stat->last_time)); + stat->last_time = cur_time; spin_unlock(&cpufreq_stats_lock); return 0; } @@ -90,8 +89,8 @@ show_time_in_state(struct cpufreq_policy *policy, char *buf) return 0; cpufreq_stats_update(stat->cpu); for (i = 0; i < stat->state_num; i++) { - len += sprintf(buf + len, "%u %llu\n", - stat->freq_table[i], stat->time_in_state[i]); + len += sprintf(buf + len, "%u %llu\n", stat->freq_table[i], + (unsigned long long)cputime64_to_clock_t(stat->time_in_state[i])); } return len; } @@ -107,16 +106,30 @@ show_trans_table(struct cpufreq_policy *policy, char *buf) if(!stat) return 0; cpufreq_stats_update(stat->cpu); + len += snprintf(buf + len, PAGE_SIZE - len, " From : To\n"); + len += snprintf(buf + len, PAGE_SIZE - len, " : "); + for (i = 0; i < stat->state_num; i++) { + if (len >= PAGE_SIZE) + break; + len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", + stat->freq_table[i]); + } + if (len >= PAGE_SIZE) + return len; + + len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + for (i = 0; i < stat->state_num; i++) { if (len >= PAGE_SIZE) break; - len += snprintf(buf + len, PAGE_SIZE - len, "%9u:\t", + + len += snprintf(buf + len, PAGE_SIZE - len, "%9u: ", stat->freq_table[i]); for (j = 0; j < stat->state_num; j++) { if (len >= PAGE_SIZE) break; - len += snprintf(buf + len, PAGE_SIZE - len, "%u\t", + len += snprintf(buf + len, PAGE_SIZE - len, "%9u ", stat->trans_table[i*stat->max_state+j]); } len += snprintf(buf + len, PAGE_SIZE - len, "\n"); @@ -197,7 +210,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, count++; } - alloc_size = count * sizeof(int) + count * sizeof(long long); + alloc_size = count * sizeof(int) + count * sizeof(cputime64_t); #ifdef CONFIG_CPU_FREQ_STAT_DETAILS alloc_size += count * count * sizeof(int); @@ -224,7 +237,7 @@ cpufreq_stats_create_table (struct cpufreq_policy *policy, } stat->state_num = j; spin_lock(&cpufreq_stats_lock); - stat->last_time = jiffies; + stat->last_time = get_jiffies_64(); stat->last_index = freq_table_get_index(stat, policy->cur); spin_unlock(&cpufreq_stats_lock); cpufreq_cpu_put(data); -- cgit v1.2.2