X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fnet%2Fqla3xxx.c;h=3cdd07c45b6dea4961a8a12422d90643a76d0c37;hb=c4e3fd940c7081a0332e9b4ea6485744075067b0;hp=ea151315050c382ff096696d7ae2a3abd2a54949;hpb=50626297b1beb0a29c0f174be39f36485533216c;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c old mode 100755 new mode 100644 index ea15131..3cdd07c --- a/drivers/net/qla3xxx.c +++ b/drivers/net/qla3xxx.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include @@ -39,7 +38,7 @@ #define DRV_NAME "qla3xxx" #define DRV_STRING "QLogic ISP3XXX Network Driver" -#define DRV_VERSION "v2.03.00-k4" +#define DRV_VERSION "v2.03.00-k5" #define PFX DRV_NAME " " static const char ql3xxx_driver_name[] = DRV_NAME; @@ -82,7 +81,7 @@ typedef enum { } PHY_DEVICE_et; typedef struct { - PHY_DEVICE_et phyDevice; + PHY_DEVICE_et phyDevice; u32 phyIdOUI; u16 phyIdModel; char *name; @@ -329,9 +328,9 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev, qdev->lrg_buffer_len - QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { - printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); dev_kfree_skb(lrg_buf_cb->skb); lrg_buf_cb->skb = NULL; @@ -541,20 +540,12 @@ static void eeprom_readword(struct ql3_adapter *qdev, fm93c56a_deselect(qdev); } -static void ql_swap_mac_addr(u8 * macAddress) +static void ql_set_mac_addr(struct net_device *ndev, u16 *addr) { -#ifdef __BIG_ENDIAN - u8 temp; - temp = macAddress[0]; - macAddress[0] = macAddress[1]; - macAddress[1] = temp; - temp = macAddress[2]; - macAddress[2] = macAddress[3]; - macAddress[3] = temp; - temp = macAddress[4]; - macAddress[4] = macAddress[5]; - macAddress[5] = temp; -#endif + __le16 *p = (__le16 *)ndev->dev_addr; + p[0] = cpu_to_le16(addr[0]); + p[1] = cpu_to_le16(addr[1]); + p[2] = cpu_to_le16(addr[2]); } static int ql_get_nvram_params(struct ql3_adapter *qdev) @@ -591,18 +582,6 @@ static int ql_get_nvram_params(struct ql3_adapter *qdev) return -1; } - /* - * We have a problem with endianness for the MAC addresses - * and the two 8-bit values version, and numPorts. We - * have to swap them on big endian systems. - */ - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn0.macAddress); - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn1.macAddress); - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn2.macAddress); - ql_swap_mac_addr(qdev->nvram_data.funcCfg_fn3.macAddress); - pEEPROMData = (u16 *) & qdev->nvram_data.version; - *pEEPROMData = le16_to_cpu(*pEEPROMData); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); return checksum; } @@ -712,7 +691,7 @@ static int ql_mii_write_reg_ex(struct ql3_adapter *qdev, if (ql_wait_for_mii_ready(qdev)) { if (netif_msg_link(qdev)) printk(KERN_WARNING PFX - "%s: Timed out waiting for management port to" + "%s: Timed out waiting for management port to " "get free before issuing command.\n", qdev->ndev->name); return -1; @@ -885,14 +864,14 @@ static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev) u16 reg; /* Enable Auto-negotiation sense */ - ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, ®, + ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, ®, PHYAddr[qdev->mac_index]); reg |= PETBI_TBI_AUTO_SENSE; - ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg, + ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg, PHYAddr[qdev->mac_index]); ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER, - PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX, + PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX, PHYAddr[qdev->mac_index]); ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG, @@ -946,7 +925,7 @@ static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr) ql_mii_write_reg_ex(qdev, 0x10, 0x2806, miiAddr); /* Write new PHYAD w/bit 5 set */ ql_mii_write_reg_ex(qdev, 0x11, 0x0020 | (PHYAddr[qdev->mac_index] >> 8), miiAddr); - /* + /* * Disable diagnostic mode bit 2 = 0 * Power up device bit 11 = 0 * Link up (on) and activity (blink) @@ -956,18 +935,18 @@ static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr) ql_mii_write_reg(qdev, 0x1c, 0xfaf0); } -static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev, +static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev, u16 phyIdReg0, u16 phyIdReg1) { PHY_DEVICE_et result = PHY_TYPE_UNKNOWN; - u32 oui; + u32 oui; u16 model; - int i; + int i; if (phyIdReg0 == 0xffff) { return result; } - + if (phyIdReg1 == 0xffff) { return result; } @@ -985,7 +964,7 @@ static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev, printk(KERN_INFO "%s: Phy: %s\n", qdev->ndev->name, PHY_DEVICES[i].name); - + break; } } @@ -1034,7 +1013,7 @@ static int ql_is_full_dup(struct ql3_adapter *qdev) { if (ql_mii_read_reg(qdev, 0x1A, ®)) return 0; - + return ((reg & 0x0080) && (reg & 0x1000)) != 0; } case PHY_VITESSE_VSC8211: @@ -1083,19 +1062,19 @@ static int PHY_Setup(struct ql3_adapter *qdev) /* Check if we have a Agere PHY */ if ((reg1 == 0xffff) || (reg2 == 0xffff)) { - /* Determine which MII address we should be using + /* Determine which MII address we should be using determined by the index of the card */ if (qdev->mac_index == 0) { miiAddr = MII_AGERE_ADDR_1; } else { miiAddr = MII_AGERE_ADDR_2; } - + err =ql_mii_read_reg_ex(qdev, PHY_ID_0_REG, ®1, miiAddr); if(err != 0) { printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n", qdev->ndev->name); - return err; + return err; } err = ql_mii_read_reg_ex(qdev, PHY_ID_1_REG, ®2, miiAddr); @@ -1104,9 +1083,9 @@ static int PHY_Setup(struct ql3_adapter *qdev) qdev->ndev->name); return err; } - + /* We need to remember to initialize the Agere PHY */ - agereAddrChangeNeeded = true; + agereAddrChangeNeeded = true; } /* Determine the particular PHY we have on board to apply @@ -1115,7 +1094,7 @@ static int PHY_Setup(struct ql3_adapter *qdev) if ((qdev->phyType == PHY_AGERE_ET1011C) && agereAddrChangeNeeded) { /* need this here so address gets changed */ - phyAgereSpecificInit(qdev, miiAddr); + phyAgereSpecificInit(qdev, miiAddr); } else if (qdev->phyType == PHY_TYPE_UNKNOWN) { printk(KERN_ERR "%s: PHY is unknown\n", qdev->ndev->name); return -EIO; @@ -1428,7 +1407,7 @@ static int ql_this_adapter_controls_port(struct ql3_adapter *qdev) static void ql_phy_reset_ex(struct ql3_adapter *qdev) { - ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET, + ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET, PHYAddr[qdev->mac_index]); } @@ -1439,7 +1418,7 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) if(qdev->phyType == PHY_AGERE_ET1011C) { /* turn off external loopback */ - ql_mii_write_reg(qdev, 0x13, 0x0000); + ql_mii_write_reg(qdev, 0x13, 0x0000); } if(qdev->mac_index == 0) @@ -1453,23 +1432,18 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) portConfiguration = PORT_CONFIG_DEFAULT; /* Set the 1000 advertisements */ - ql_mii_read_reg_ex(qdev, PHY_GIG_CONTROL, ®, + ql_mii_read_reg_ex(qdev, PHY_GIG_CONTROL, ®, PHYAddr[qdev->mac_index]); reg &= ~PHY_GIG_ALL_PARAMS; - if(portConfiguration & - PORT_CONFIG_FULL_DUPLEX_ENABLED & - PORT_CONFIG_1000MB_SPEED) { - reg |= PHY_GIG_ADV_1000F; - } - - if(portConfiguration & - PORT_CONFIG_HALF_DUPLEX_ENABLED & - PORT_CONFIG_1000MB_SPEED) { - reg |= PHY_GIG_ADV_1000H; + if(portConfiguration & PORT_CONFIG_1000MB_SPEED) { + if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) + reg |= PHY_GIG_ADV_1000F; + else + reg |= PHY_GIG_ADV_1000H; } - ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg, + ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg, PHYAddr[qdev->mac_index]); /* Set the 10/100 & pause negotiation advertisements */ @@ -1483,7 +1457,7 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) { if(portConfiguration & PORT_CONFIG_100MB_SPEED) reg |= PHY_NEG_ADV_100F; - + if(portConfiguration & PORT_CONFIG_10MB_SPEED) reg |= PHY_NEG_ADV_10F; } @@ -1491,22 +1465,22 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev) if(portConfiguration & PORT_CONFIG_HALF_DUPLEX_ENABLED) { if(portConfiguration & PORT_CONFIG_100MB_SPEED) reg |= PHY_NEG_ADV_100H; - + if(portConfiguration & PORT_CONFIG_10MB_SPEED) reg |= PHY_NEG_ADV_10H; } if(portConfiguration & PORT_CONFIG_1000MB_SPEED) { - reg |= 1; + reg |= 1; } - ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg, + ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg, PHYAddr[qdev->mac_index]); ql_mii_read_reg_ex(qdev, CONTROL_REG, ®, PHYAddr[qdev->mac_index]); - - ql_mii_write_reg_ex(qdev, CONTROL_REG, + + ql_mii_write_reg_ex(qdev, CONTROL_REG, reg | PHY_CTRL_RESTART_NEG | PHY_CTRL_AUTO_NEG, PHYAddr[qdev->mac_index]); } @@ -1646,8 +1620,11 @@ static int ql_finish_auto_neg(struct ql3_adapter *qdev) return 0; } -static void ql_link_state_machine(struct ql3_adapter *qdev) +static void ql_link_state_machine_work(struct work_struct *work) { + struct ql3_adapter *qdev = + container_of(work, struct ql3_adapter, link_state_work.work); + u32 curr_link_state; unsigned long hw_flags; @@ -1661,7 +1638,11 @@ static void ql_link_state_machine(struct ql3_adapter *qdev) "%s: Reset in progress, skip processing link " "state.\n", qdev->ndev->name); - spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); + spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); + + /* Restart timer on 2 second interval. */ + mod_timer(&qdev->adapter_timer, jiffies + HZ * 1);\ + return; } @@ -1706,6 +1687,9 @@ static void ql_link_state_machine(struct ql3_adapter *qdev) break; } spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); + + /* Restart timer on 2 second interval. */ + mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); } /* @@ -1753,7 +1737,7 @@ static int ql_mii_setup(struct ql3_adapter *qdev) return -1; if (qdev->device_id == QL3032_DEVICE_ID) - ql_write_page0_reg(qdev, + ql_write_page0_reg(qdev, &port_regs->macMIIMgmtControlReg, 0x0f00000); /* Divide 125MHz clock by 28 to meet PHY timing requirements */ @@ -1866,8 +1850,6 @@ static void ql_get_drvinfo(struct net_device *ndev, strncpy(drvinfo->version, ql3xxx_driver_version, 32); strncpy(drvinfo->fw_version, "N/A", 32); strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32); - drvinfo->n_stats = 0; - drvinfo->testinfo_len = 0; drvinfo->regdump_len = 0; drvinfo->eedump_len = 0; } @@ -1937,9 +1919,9 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { - printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); dev_kfree_skb(lrg_buf_cb->skb); lrg_buf_cb->skb = NULL; @@ -2047,14 +2029,14 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) { printk(KERN_WARNING "Frame short but, frame was padded and sent.\n"); } - + tx_cb = &qdev->tx_buf[mac_rsp->transaction_id]; /* Check the transmit response flags for any errors */ if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) { printk(KERN_ERR "Frame too short to be legal, frame not sent.\n"); - qdev->stats.tx_errors++; + qdev->ndev->stats.tx_errors++; retval = -EIO; goto frame_not_sent; } @@ -2062,7 +2044,7 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, if(tx_cb->seg_count == 0) { printk(KERN_ERR "tx_cb->seg_count == 0: %d\n", mac_rsp->transaction_id); - qdev->stats.tx_errors++; + qdev->ndev->stats.tx_errors++; retval = -EIO; goto invalid_seg_count; } @@ -2081,8 +2063,8 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev, PCI_DMA_TODEVICE); } } - qdev->stats.tx_packets++; - qdev->stats.tx_bytes += tx_cb->skb->len; + qdev->ndev->stats.tx_packets++; + qdev->ndev->stats.tx_bytes += tx_cb->skb->len; frame_not_sent: dev_kfree_skb_irq(tx_cb->skb); @@ -2111,13 +2093,13 @@ static struct ql_rcv_buf_cb *ql_get_lbuf(struct ql3_adapter *qdev) /* * The difference between 3022 and 3032 for inbound completions: - * 3022 uses two buffers per completion. The first buffer contains - * (some) header info, the second the remainder of the headers plus - * the data. For this chip we reserve some space at the top of the - * receive buffer so that the header info in buffer one can be - * prepended to the buffer two. Buffer two is the sent up while + * 3022 uses two buffers per completion. The first buffer contains + * (some) header info, the second the remainder of the headers plus + * the data. For this chip we reserve some space at the top of the + * receive buffer so that the header info in buffer one can be + * prepended to the buffer two. Buffer two is the sent up while * buffer one is returned to the hardware to be reused. - * 3032 receives all of it's data and headers in one buffer for a + * 3032 receives all of it's data and headers in one buffer for a * simpler process. 3032 also supports checksum verification as * can be seen in ql_process_macip_rx_intr(). */ @@ -2141,8 +2123,8 @@ static void ql_process_mac_rx_intr(struct ql3_adapter *qdev, lrg_buf_cb2 = ql_get_lbuf(qdev); skb = lrg_buf_cb2->skb; - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; + qdev->ndev->stats.rx_packets++; + qdev->ndev->stats.rx_bytes += length; skb_put(skb, length); pci_unmap_single(qdev->pdev, @@ -2208,13 +2190,13 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, skb_push(skb2, size), size); } else { u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum); - if (checksum & - (IB_IP_IOCB_RSP_3032_ICE | - IB_IP_IOCB_RSP_3032_CE)) { + if (checksum & + (IB_IP_IOCB_RSP_3032_ICE | + IB_IP_IOCB_RSP_3032_CE)) { printk(KERN_ERR "%s: Bad checksum for this %s packet, checksum = %x.\n", __func__, - ((checksum & + ((checksum & IB_IP_IOCB_RSP_3032_TCP) ? "TCP" : "UDP"),checksum); } else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) || @@ -2226,8 +2208,8 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev, skb2->protocol = eth_type_trans(skb2, qdev->ndev); netif_receive_skb(skb2); - qdev->stats.rx_packets++; - qdev->stats.rx_bytes += length; + ndev->stats.rx_packets++; + ndev->stats.rx_bytes += length; ndev->last_rx = jiffies; lrg_buf_cb2->skb = NULL; @@ -2310,27 +2292,19 @@ static int ql_tx_rx_clean(struct ql3_adapter *qdev, return work_done; } -static int ql_poll(struct net_device *ndev, int *budget) +static int ql_poll(struct napi_struct *napi, int budget) { - struct ql3_adapter *qdev = netdev_priv(ndev); - int work_to_do = min(*budget, ndev->quota); + struct ql3_adapter *qdev = container_of(napi, struct ql3_adapter, napi); + struct net_device *ndev = qdev->ndev; int rx_cleaned = 0, tx_cleaned = 0; unsigned long hw_flags; struct ql3xxx_port_registers __iomem *port_regs = qdev->mem_map_registers; - if (!netif_carrier_ok(ndev)) - goto quit_polling; - - ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, work_to_do); - *budget -= rx_cleaned; - ndev->quota -= rx_cleaned; - - if( tx_cleaned + rx_cleaned != work_to_do || - !netif_running(ndev)) { -quit_polling: - netif_rx_complete(ndev); + ql_tx_rx_clean(qdev, &tx_cleaned, &rx_cleaned, budget); + if (tx_cleaned + rx_cleaned != budget) { spin_lock_irqsave(&qdev->hw_lock, hw_flags); + __netif_rx_complete(ndev, napi); ql_update_small_bufq_prod_index(qdev); ql_update_lrg_bufq_prod_index(qdev); writel(qdev->rsp_consumer_index, @@ -2338,9 +2312,8 @@ quit_polling: spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); ql_enable_interrupts(qdev); - return 0; } - return 1; + return tx_cleaned + rx_cleaned; } static irqreturn_t ql3xxx_isr(int irq, void *dev_id) @@ -2390,8 +2363,8 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) spin_unlock(&qdev->adapter_lock); } else if (value & ISP_IMR_DISABLE_CMPL_INT) { ql_disable_interrupts(qdev); - if (likely(netif_rx_schedule_prep(ndev))) { - __netif_rx_schedule(ndev); + if (likely(netif_rx_schedule_prep(ndev, &qdev->napi))) { + __netif_rx_schedule(ndev, &qdev->napi); } } else { return IRQ_NONE; @@ -2401,12 +2374,12 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id) } /* - * Get the total number of segments needed for the + * Get the total number of segments needed for the * given number of fragments. This is necessary because * outbound address lists (OAL) will be used when more than - * two frags are given. Each address list has 5 addr/len + * two frags are given. Each address list has 5 addr/len * pairs. The 5th pair in each AOL is used to point to - * the next AOL if more frags are coming. + * the next AOL if more frags are coming. * That is why the frags:segment count ratio is not linear. */ static int ql_get_seg_count(struct ql3_adapter *qdev, @@ -2481,14 +2454,14 @@ static int ql_send_map(struct ql3_adapter *qdev, */ map = pci_map_single(qdev->pdev, skb->data, len, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { - printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", + printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); return NETDEV_TX_BUSY; } - + oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low; oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map)); oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map)); @@ -2499,8 +2472,7 @@ static int ql_send_map(struct ql3_adapter *qdev, if (seg_cnt == 1) { /* Terminate the last segment. */ - oal_entry->len = - cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); + oal_entry->len |= cpu_to_le32(OAL_LAST_ENTRY); } else { oal = tx_cb->oal; for (completed_segs=0; completed_segspdev, map); if(err) { - printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", + printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", qdev->ndev->name, err); goto map_error; } @@ -2542,9 +2514,9 @@ static int ql_send_map(struct ql3_adapter *qdev, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { - printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", + printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", qdev->ndev->name, err); goto map_error; } @@ -2557,18 +2529,17 @@ static int ql_send_map(struct ql3_adapter *qdev, frag->size); } /* Terminate the last segment. */ - oal_entry->len = - cpu_to_le32(le32_to_cpu(oal_entry->len) | OAL_LAST_ENTRY); + oal_entry->len |= cpu_to_le32(OAL_LAST_ENTRY); } return NETDEV_TX_OK; map_error: /* A PCI mapping failed and now we will need to back out - * We need to traverse through the oal's and associated pages which + * We need to traverse through the oal's and associated pages which * have been mapped and now we must unmap them to clean up properly */ - + seg = 1; oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low; oal = tx_cb->oal; @@ -2606,11 +2577,11 @@ map_error: * The difference between 3022 and 3032 sends: * 3022 only supports a simple single segment transmission. * 3032 supports checksumming and scatter/gather lists (fragments). - * The 3032 supports sglists by using the 3 addr/len pairs (ALP) - * in the IOCB plus a chain of outbound address lists (OAL) that - * each contain 5 ALPs. The last ALP of the IOCB (3rd) or OAL (5th) - * will used to point to an OAL when more ALP entries are required. - * The IOCB is always the top of the chain followed by one or more + * The 3032 supports sglists by using the 3 addr/len pairs (ALP) + * in the IOCB plus a chain of outbound address lists (OAL) that + * each contain 5 ALPs. The last ALP of the IOCB (3rd) or OAL (5th) + * will used to point to an OAL when more ALP entries are required. + * The IOCB is always the top of the chain followed by one or more * OALs (when necessary). */ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) @@ -2624,14 +2595,14 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) if (unlikely(atomic_read(&qdev->tx_count) < 2)) { return NETDEV_TX_BUSY; } - + tx_cb = &qdev->tx_buf[qdev->req_producer_index] ; if((tx_cb->seg_count = ql_get_seg_count(qdev, (skb_shinfo(skb)->nr_frags))) == -1) { printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__); return NETDEV_TX_OK; } - + mac_iocb_ptr = tx_cb->queue_entry; memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req)); mac_iocb_ptr->opcode = qdev->mac_ob_opcode; @@ -2643,12 +2614,12 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev) if (qdev->device_id == QL3032_DEVICE_ID && skb->ip_summed == CHECKSUM_PARTIAL) ql_hw_csum_setup(skb, mac_iocb_ptr); - + if(ql_send_map(qdev,mac_iocb_ptr,tx_cb,skb) != NETDEV_TX_OK) { printk(KERN_ERR PFX"%s: Could not map the segments!\n",__func__); return NETDEV_TX_BUSY; } - + wmb(); qdev->req_producer_index++; if (qdev->req_producer_index == NUM_REQ_Q_ENTRIES) @@ -2746,7 +2717,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) "%s: qdev->lrg_buf alloc failed.\n", qdev->ndev->name); return -ENOMEM; } - + qdev->lrg_buf_q_alloc_virt_addr = pci_alloc_consistent(qdev->pdev, qdev->lrg_buf_q_alloc_size, @@ -2945,7 +2916,7 @@ static int ql_alloc_large_buffers(struct ql3_adapter *qdev) QL_HEADER_SPACE, PCI_DMA_FROMDEVICE); - err = pci_dma_mapping_error(map); + err = pci_dma_mapping_error(qdev->pdev, map); if(err) { printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", qdev->ndev->name, err); @@ -3042,7 +3013,7 @@ static int ql_alloc_mem_resources(struct ql3_adapter *qdev) LS_64BITS(qdev->shadow_reg_phy_addr); qdev->prsp_producer_index = - (u32 *) (((u8 *) qdev->preq_consumer_index) + 8); + (__le32 *) (((u8 *) qdev->preq_consumer_index) + 8); qdev->rsp_producer_index_phy_addr_high = qdev->req_consumer_index_phy_addr_high; qdev->rsp_producer_index_phy_addr_low = @@ -3222,7 +3193,7 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) ql_write_page1_reg(qdev, &hmem_regs->reqLength, NUM_REQ_Q_ENTRIES); /* Response Queue Registers */ - *((u16 *) (qdev->prsp_producer_index)) = 0; + *((__le16 *) (qdev->prsp_producer_index)) = 0; qdev->rsp_consumer_index = 0; qdev->rsp_current = qdev->rsp_q_virt_addr; @@ -3524,8 +3495,6 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) case ISP_CONTROL_FN0_NET: qdev->mac_index = 0; qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number; - qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number; - qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number; qdev->mb_bit_mask = FN0_MA_BITS_MASK; qdev->PHYAddr = PORT0_PHY_ADDRESS; if (port_status & PORT_STATUS_SM0) @@ -3537,8 +3506,6 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) case ISP_CONTROL_FN1_NET: qdev->mac_index = 1; qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number; - qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number; - qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number; qdev->mb_bit_mask = FN1_MA_BITS_MASK; qdev->PHYAddr = PORT1_PHY_ADDRESS; if (port_status & PORT_STATUS_SM1) @@ -3555,13 +3522,14 @@ static void ql_set_mac_info(struct ql3_adapter *qdev) qdev->ndev->name,value); break; } - qdev->numPorts = qdev->nvram_data.numPorts; + qdev->numPorts = qdev->nvram_data.version_and_numPorts >> 8; } static void ql_display_dev_info(struct net_device *ndev) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); struct pci_dev *pdev = qdev->pdev; + DECLARE_MAC_BUF(mac); printk(KERN_INFO PFX "\n%s Adapter %d RevisionID %d found %s on PCI slot %d.\n", @@ -3587,10 +3555,8 @@ static void ql_display_dev_info(struct net_device *ndev) if (netif_msg_probe(qdev)) printk(KERN_INFO PFX - "%s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n", - ndev->name, ndev->dev_addr[0], ndev->dev_addr[1], - ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4], - ndev->dev_addr[5]); + "%s: MAC address %s\n", + ndev->name, print_mac(mac, ndev->dev_addr)); } static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) @@ -3617,7 +3583,7 @@ static int ql_adapter_down(struct ql3_adapter *qdev, int do_reset) del_timer_sync(&qdev->adapter_timer); - netif_poll_disable(ndev); + napi_disable(&qdev->napi); if (do_reset) { int soft_reset; @@ -3705,7 +3671,7 @@ static int ql_adapter_up(struct ql3_adapter *qdev) mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); - netif_poll_enable(ndev); + napi_enable(&qdev->napi); ql_enable_interrupts(qdev); return 0; @@ -3731,7 +3697,9 @@ static int ql_cycle_adapter(struct ql3_adapter *qdev, int reset) printk(KERN_ERR PFX "%s: Driver up/down cycle failed, " "closing device\n",qdev->ndev->name); + rtnl_lock(); dev_close(qdev->ndev); + rtnl_unlock(); return -1; } return 0; @@ -3758,20 +3726,6 @@ static int ql3xxx_open(struct net_device *ndev) return (ql_adapter_up(qdev)); } -static struct net_device_stats *ql3xxx_get_stats(struct net_device *dev) -{ - struct ql3_adapter *qdev = (struct ql3_adapter *)dev->priv; - return &qdev->stats; -} - -static void ql3xxx_set_multicast_list(struct net_device *ndev) -{ - /* - * We are manually parsing the list in the net_device structure. - */ - return; -} - static int ql3xxx_set_mac_address(struct net_device *ndev, void *p) { struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev); @@ -3955,19 +3909,7 @@ static void ql_get_board_info(struct ql3_adapter *qdev) static void ql3xxx_timer(unsigned long ptr) { struct ql3_adapter *qdev = (struct ql3_adapter *)ptr; - - if (test_bit(QL_RESET_ACTIVE,&qdev->flags)) { - printk(KERN_DEBUG PFX - "%s: Reset in progress.\n", - qdev->ndev->name); - goto end; - } - - ql_link_state_machine(qdev); - - /* Restart timer on 2 second interval. */ -end: - mod_timer(&qdev->adapter_timer, jiffies + HZ * 1); + queue_delayed_work(qdev->workqueue, &qdev->link_state_work, 0); } static int __devinit ql3xxx_probe(struct pci_dev *pdev, @@ -4016,7 +3958,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, goto err_out_free_regions; } - SET_MODULE_OWNER(ndev); SET_NETDEV_DEV(ndev, &pdev->dev); pci_set_drvdata(pdev, ndev); @@ -4054,15 +3995,17 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, ndev->open = ql3xxx_open; ndev->hard_start_xmit = ql3xxx_send; ndev->stop = ql3xxx_close; - ndev->get_stats = ql3xxx_get_stats; - ndev->set_multicast_list = ql3xxx_set_multicast_list; + /* ndev->set_multicast_list + * This device is one side of a two-function adapter + * (NIC and iSCSI). Promiscuous mode setting/clearing is + * not allowed from the NIC side. + */ SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops); ndev->set_mac_address = ql3xxx_set_mac_address; ndev->tx_timeout = ql3xxx_tx_timeout; ndev->watchdog_timeo = 5 * HZ; - ndev->poll = &ql_poll; - ndev->weight = 64; + netif_napi_add(ndev, &qdev->napi, ql_poll, 64); ndev->irq = pdev->irq; @@ -4080,20 +4023,15 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, /* Validate and set parameters */ if (qdev->mac_index) { ndev->mtu = qdev->nvram_data.macCfg_port1.etherMtu_mac ; - memcpy(ndev->dev_addr, &qdev->nvram_data.funcCfg_fn2.macAddress, - ETH_ALEN); + ql_set_mac_addr(ndev, qdev->nvram_data.funcCfg_fn2.macAddress); } else { ndev->mtu = qdev->nvram_data.macCfg_port0.etherMtu_mac ; - memcpy(ndev->dev_addr, &qdev->nvram_data.funcCfg_fn0.macAddress, - ETH_ALEN); + ql_set_mac_addr(ndev, qdev->nvram_data.funcCfg_fn0.macAddress); } memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); ndev->tx_queue_len = NUM_REQ_Q_ENTRIES; - /* Turn off support for multicasting */ - ndev->flags &= ~IFF_MULTICAST; - /* Record PCI bus information. */ ql_get_board_info(qdev); @@ -4120,6 +4058,7 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, qdev->workqueue = create_singlethread_workqueue(ndev->name); INIT_DELAYED_WORK(&qdev->reset_work, ql_reset_work); INIT_DELAYED_WORK(&qdev->tx_timeout_work, ql_tx_timeout_work); + INIT_DELAYED_WORK(&qdev->link_state_work, ql_link_state_machine_work); init_timer(&qdev->adapter_timer); qdev->adapter_timer.function = ql3xxx_timer;