Linsys Contractor Amit S. Kale wrote:
+/**
+ * netxen_nic_set_multi - Multicast
+ **/
+void netxen_nic_set_multi(struct net_device *netdev)
+{
+    struct netxen_port *port = netdev_priv(netdev);
+    struct dev_mc_list *mc_ptr;
+
+    mc_ptr = netdev->mc_list;
+    if (netdev->flags & IFF_PROMISC)
+        netxen_nic_set_promisc_mode(port);
+    else
+        netxen_nic_unset_promisc_mode(port);
+}

This appears unfinished, it does not handle multicast at all.



+int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu)
+{
+    struct netxen_port *port = netdev_priv(netdev);
+
+    if (new_mtu & 0xffff0000)
+        return -EINVAL;
+
+    if (new_mtu > 8000) {

please use named constants here, rather than magic numbers


+        printk(KERN_ERR "%s: %s MTU > 8000 is not supported\n",
+               netxen_nic_driver_name, netdev->name);
+        return -EINVAL;
+    }
+
+    netxen_nic_set_mtu(port, new_mtu);
+    netdev->mtu = new_mtu;
+
+    return 0;
+}
+
+/*
+ * check if the firmware has been downloaded and ready to run  and
+ * setup the address for the descriptors in the adapter
+ */

ah hah! so you do have a firmware! Well, export that version via ethtool...



+/*
+ * Changes the CRB window to the specified window.
+ */
+void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw)
+{
+    struct netxen_pcix_crb_window window;
+    unsigned long offset;
+    u32 tmp;
+
+    if (adapter->curr_window == wndw)
+        return;
+
+    /*
+     * Move the CRB window.
+     * We need to write to the "direct access" region of PCI
+     * to avoid a race condition where the window register has
+     * not been successfully written across CRB before the target
+     * register address is received by PCI. The direct region bypasses
+     * the CRB bus.
+     */
+    offset = adapter->ahw.pci_base + NETXEN_PCIX_PH_REG(PCIX_CRB_WINDOW);
+
+    *(netxen_crbword_t *) & window = 0;

WTF is this code doing?  It looks quite wrong...


+    window.addrbit = wndw;
+    writel(*(unsigned int *)&window, (void *)(offset));

bug:  code is backwards.  was this code ever tested?


+    /* MUST make sure window is set before we forge on... */
+    while ((tmp = readl((void *)offset)) != *(u32 *) & window)
+        printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
+               "registered properly: 0x%08x.\n",
+               netxen_nic_driver_name, __FUNCTION__, tmp);

infinite printk loop.


+    adapter->curr_window = wndw;
+}
+
+/*
+ * Set the CRB window based on the offset.
+ */
+static inline unsigned long
+netxen_nic_pci_set_crbwindow(struct netxen_adapter *adapter, u64 off)
+{
+    /*
+     * See if we are currently pointing to the region we want to use next.
+     */
+
+    if ((off >= NETXEN_CRB_PCIX_HOST) && (off < NETXEN_CRB_DDR_NET)) {
+        /*
+         * No need to change window. PCIX and PCIE regs are in both
+         * windows.
+         */
+        return off;
+    }
+
+    if ((off >= NETXEN_CRB_PCIX_HOST) && (off < NETXEN_CRB_PCIX_HOST2)) {
+        /* We are in first CRB window */
+        if (adapter->curr_window != 0)
+            netxen_nic_pci_change_crbwindow(adapter, 0);
+
+        return off;
+    }
+
+    if ((off > NETXEN_CRB_PCIX_HOST2) && (off < NETXEN_CRB_MAX)) {
+        /* We are in second CRB window */
+        off = off - NETXEN_CRB_PCIX_HOST2 + NETXEN_CRB_PCIX_HOST;
+
+        if (adapter->curr_window != 1)
+            netxen_nic_pci_change_crbwindow(adapter, 1);
+
+        return off;
+    }
+
+    if ((off >= NETXEN_PCI_DIRECT_CRB) && (off < NETXEN_PCI_CAMQM_MAX)) {
+        /*
+         * We are in the QM or direct access register region - do
+         * nothing
+         */
+        return off;
+    }
+
+    /* strange address given */
+    dump_stack();
+    printk(KERN_WARNING
+           "%s: Warning: netxen_nic_pci_set_crbwindow called with"
+           " an unknown address(%llx)\n", netxen_nic_driver_name, off);
+
+    return off;
+}
+
+int
+netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data,
+               int len)
+{
+    void *addr;
+    unsigned long flags = 0;
+
+    if (ADDR_IN_WINDOW1(off)) {
+        addr = NETXEN_CRB_NORMALIZE(adapter, off);
+        read_lock(&adapter->adapter_lock);
+    } else {        /* Window 0 */
+        addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        netxen_nic_pci_change_crbwindow(adapter, 0);
+    }
+
+    DPRINTK(INFO, "writing to base %lx offset %llx addr %p"
+        " data %llx len %d\n",
+        adapter->ahw.pci_base, off, addr,
+        *(unsigned long long *)data, len);
+    switch (len) {
+    case 1:
+        writeb(*(u8 *) data, addr);
+        break;
+    case 2:
+        writew(*(u16 *) data, addr);
+        break;
+    case 4:
+        writel(*(u32 *) data, addr);
+        break;
+    case 8:
+        writeq(*(u64 *) data, addr);
+        break;
+    default:
+        DPRINTK(INFO,
+            "writing data %lx to offset %llx, num words=%d\n",
+            *(unsigned long *)data, off, (len >> 3));
+
+        NETXEN_NIC_HW_BLOCK_WRITE_64(data, addr, (len >> 3));
+        break;
+    }
+    if (ADDR_IN_WINDOW1(off))
+        read_unlock(&adapter->adapter_lock);
+    else {            /* Window 0 */
+        netxen_nic_pci_change_crbwindow(adapter, 1);
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+    }

buggy locking?  you read-lock when writing to registers.


+int
+netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data,
+              int len)
+{
+    void *addr;
+    unsigned long flags = 0;
+
+    if (ADDR_IN_WINDOW1(off)) {    /* Window 1 */
+        addr = NETXEN_CRB_NORMALIZE(adapter, off);
+        read_lock(&adapter->adapter_lock);
+    } else {        /* Window 0 */
+        addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        netxen_nic_pci_change_crbwindow(adapter, 0);
+    }
+
+    DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
+        adapter->ahw.pci_base, off, addr);
+    switch (len) {
+    case 1:
+        *(u8 *) data = readb(addr);
+        break;
+    case 2:
+        *(u16 *) data = readw(addr);
+        break;
+    case 4:
+        *(u32 *) data = readl(addr);
+        break;
+    case 8:
+        *(u64 *) data = readq(addr);
+        break;
+    default:
+        NETXEN_NIC_HW_BLOCK_READ_64(data, addr, (len >> 3));
+        break;
+    }
+    DPRINTK(INFO, "read %lx\n", *(unsigned long *)data);
+
+    if (ADDR_IN_WINDOW1(off))
+        read_unlock(&adapter->adapter_lock);
+    else {            /* Window 0 */
+        netxen_nic_pci_change_crbwindow(adapter, 1);
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+    }
+
+    return 0;
+}
+
+void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
+{                /* Only for window 1 */
+    void *addr;
+
+    read_lock(&adapter->adapter_lock);
+
+    if (adapter->curr_window != 1)
+        netxen_nic_pci_change_crbwindow(adapter, 1);
+    addr = NETXEN_CRB_NORMALIZE(adapter, off);
+    DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n",
+        adapter->ahw.pci_base, off, addr, val);
+    writel(val, addr);
+
+    read_unlock(&adapter->adapter_lock);
+}
+
+int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
+{                /* Only for window 1 */
+    void *addr;
+    int val;
+
+    read_lock(&adapter->adapter_lock);
+    addr = NETXEN_CRB_NORMALIZE(adapter, off);
+    DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n",
+        adapter->ahw.pci_base, off, addr);
+    val = readl(addr);
+    writel(val, addr);
+    read_unlock(&adapter->adapter_lock);
+
+    return val;
+}
+
+/* Change the window to 0, write and change back to window 1. */
+void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
+{
+    unsigned long flags;
+    void *addr;
+
+    write_lock_irqsave(&adapter->adapter_lock, flags);
+    netxen_nic_pci_change_crbwindow(adapter, 0);
+    addr = (void *)(adapter->ahw.pci_base + index);
+    writel(value, addr);
+    netxen_nic_pci_change_crbwindow(adapter, 1);
+    write_unlock_irqrestore(&adapter->adapter_lock, flags);
+}
+
+/* Change the window to 0, read and change back to window 1. */
+void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value)
+{
+    unsigned long flags;
+    void *addr;
+
+    addr = (void *)(adapter->ahw.pci_base + index);
+
+    write_lock_irqsave(&adapter->adapter_lock, flags);
+    netxen_nic_pci_change_crbwindow(adapter, 0);
+    *value = readl(addr);
+    netxen_nic_pci_change_crbwindow(adapter, 1);
+    write_unlock_irqrestore(&adapter->adapter_lock, flags);
+}

highly sub-optimal, deadlock-prone locking.

every register read/write should not acquire a lock.


+static unsigned long
+netxen_nic_pci_set_window(unsigned long long pci_base, unsigned long long addr)
+{
+    static int ddr_mn_window = -1;
+    static int qdr_sn_window = -1;
+    int window;
+
+ if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
+        /* DDR network side */
+        addr -= NETXEN_ADDR_DDR_NET;
+        window = (addr >> 25) & 0x3ff;
+        if (ddr_mn_window != window) {
+            ddr_mn_window = window;
+            writel(window, (void *)(ptrdiff_t) (pci_base +
+                                NETXEN_PCIX_PH_REG
+                                (PCIX_MN_WINDOW)));
+            /* MUST make sure window is set before we forge on... */
+            readl((void *)(ptrdiff_t) (pci_base +
+                           NETXEN_PCIX_PH_REG
+                           (PCIX_MN_WINDOW)));
+        }
+        addr -= (window * 0x2000000);
+        addr += NETXEN_PCI_DDR_NET;
+ } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
+        addr -= NETXEN_ADDR_OCM0;
+        addr += NETXEN_PCI_OCM0;
+ } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
+        addr -= NETXEN_ADDR_OCM1;
+        addr += NETXEN_PCI_OCM1;
+    } else
+        if (ADDR_IN_RANGE
+        (addr, NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX)) {
+        /* QDR network side */
+        addr -= NETXEN_ADDR_QDR_NET;
+        window = (addr >> 22) & 0x3f;
+        if (qdr_sn_window != window) {
+            qdr_sn_window = window;
+            writel((window << 22),
+                   (void *)(ptrdiff_t) (pci_base +
+                            NETXEN_PCIX_PH_REG
+                            (PCIX_SN_WINDOW)));
+            /* MUST make sure window is set before we forge on... */
+            readl((void *)(ptrdiff_t) (pci_base +
+                           NETXEN_PCIX_PH_REG
+                           (PCIX_SN_WINDOW)));
+        }
+        addr -= (window * 0x400000);
+        addr += NETXEN_PCI_QDR_NET;
+    } else {
+        /*
+         * peg gdb frequently accesses memory that doesn't exist,
+         * this limits the chit chat so debugging isn't slowed down.
+         */
+        if ((netxen_pci_set_window_warning_count++ < 8)
+            || (netxen_pci_set_window_warning_count % 64 == 0))
+            printk("%s: Warning:netxen_nic_pci_set_window()"
+                   " Unknown address range!\n",
+                   netxen_nic_driver_name);
+
+    }
+    return addr;
+}
+
+/* read num_words from hardware (num_words in 64 bits    */
+void
+netxen_nic_mem_block_read(struct netxen_adapter *adapter, u64 off,
+              void *data, int num_words)
+{
+    void *addr;
+    unsigned long flags;
+
+    write_lock_irqsave(&adapter->adapter_lock, flags);
+    off = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+    addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+    DPRINTK(INFO, "reading from base %lx offset %lx addr %p\n",
+        adapter->ahw.pci_base, (unsigned long)off, addr);
+    NETXEN_NIC_HW_BLOCK_READ_64(data, addr, num_words);
+    write_unlock_irqrestore(&adapter->adapter_lock, flags);
+}
+
+int
+netxen_nic_pci_mem_write(struct netxen_adapter *adapter, u64 off,
+             void *data, int size)
+{
+    unsigned long flags;
+    void *addr;
+    int ret = 0;
+
+    write_lock_irqsave(&adapter->adapter_lock, flags);
+    off = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+    addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+    DPRINTK(INFO, "writing data %llx to offset %llx\n",
+        *(unsigned long long *)data, off);
+    switch (size) {
+    case 1:
+        writeb(*(u8 *) data, addr);
+        break;
+    case 2:
+        writew(*(u16 *) data, addr);
+        break;
+    case 4:
+        writel(*(u32 *) data, addr);
+        break;
+    case 8:
+        writeq(*(u64 *) data, addr);
+        break;
+    default:
+        ret = 1;
+        break;
+    }
+    write_unlock_irqrestore(&adapter->adapter_lock, flags);
+    DPRINTK(INFO, "wrote %llx\n", *(unsigned long long *)data);
+
+    return ret;
+}
+
+int
+netxen_nic_pci_mem_read(struct netxen_adapter *adapter,
+            u64 off, void *data, int size)
+{
+    unsigned long flags;
+    void *addr;
+    int ret = 0;
+
+    if (data == NULL || off > NETXEN_MEMADDR_MAX) {
+        printk(KERN_ERR "data: %p off:%llx\n", data, off);
+        return 1;
+    }
+    write_lock_irqsave(&adapter->adapter_lock, flags);
+    off = netxen_nic_pci_set_window(adapter->ahw.pci_base, off);
+    addr = (void *)(ptrdiff_t) (adapter->ahw.pci_base + off);
+    switch (size) {
+    case 1:
+        *(u8 *) data = readb(addr);
+        break;
+    case 2:
+        *(u16 *) data = readw(addr);
+        break;
+    case 4:
+        *(u32 *) data = readl(addr);
+        break;
+    case 8:
+        *(u64 *) data = readq(addr);
+        break;
+    default:
+        ret = 1;
+        break;
+    }
+    write_unlock_irqrestore(&adapter->adapter_lock, flags);
+    DPRINTK(INFO, "read %llx\n", *(unsigned long long *)data);
+
+    return ret;
+}

Delete the above routines and just open-code the register accesses.


+int netxen_nic_get_board_info(struct netxen_adapter *adapter)
+{
+    int rv = 0;
+    int addr = BRDCFG_START;
+    struct netxen_board_info *boardinfo;
+    int index;
+    u32 *ptr32;
+
+    boardinfo = &adapter->ahw.boardcfg;
+    ptr32 = (u32 *) boardinfo;
+
+ for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
+         index++) {
+        if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
+            rv = -1;
+            return rv;
+        }
+        ptr32++;
+        addr += sizeof(u32);
+    }
+    if (boardinfo->magic != NETXEN_BDINFO_MAGIC) {
+        printk("%s: ERROR reading %s board config."
+               " Read %x, expected %x\n", netxen_nic_driver_name,
+               netxen_nic_driver_name,
+               boardinfo->magic, NETXEN_BDINFO_MAGIC);
+        rv = -1;
+    }
+    if (boardinfo->header_version != NETXEN_BDINFO_VERSION) {
+        printk("%s: Unknown board config version."
+               " Read %x, expected %x\n", netxen_nic_driver_name,
+               boardinfo->header_version, NETXEN_BDINFO_VERSION);
+        rv = -1;
+    }
+
+    DPRINTK(INFO, "Discovered board type:0x%x  ", boardinfo->board_type);
+    switch ((netxen_brdtype_t) boardinfo->board_type) {
+    case NETXEN_BRDTYPE_P2_SB35_4G:
+        adapter->ahw.board_type = NETXEN_NIC_GBE;
+        break;
+    case NETXEN_BRDTYPE_P2_SB31_10G:
+    case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
+    case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
+    case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+        adapter->ahw.board_type = NETXEN_NIC_XGBE;
+        break;
+    case NETXEN_BRDTYPE_P1_BD:
+    case NETXEN_BRDTYPE_P1_SB:
+    case NETXEN_BRDTYPE_P1_SMAX:
+    case NETXEN_BRDTYPE_P1_SOCK:
+        adapter->ahw.board_type = NETXEN_NIC_GBE;
+        break;
+    default:
+        printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
+               boardinfo->board_type);
+        break;
+    }
+
+    return rv;
+}
+
+inline int netxen_nic_get_board_num(struct netxen_adapter *adapter)
+{
+    return adapter->ahw.boardcfg.board_num;
+}
+
+/* NIU access sections */
+
+/* Set the MAC address for a port */
+int netxen_nic_macaddr_set(struct netxen_port *port, u8 * addr)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    int phy = port->portnum, ret = 0;
+
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        ret = netxen_niu_macaddr_set(adapter, phy, addr);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        ret = netxen_niu_xg_macaddr_set(adapter, phy, addr);
+        break;
+
+    default:
+        dump_stack();
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+/* Return the current MAC address of the given port. */
+int netxen_nic_macaddr_get(struct netxen_port *port, u8 ** addr)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    int phy = port->portnum;
+    int ret = 0;
+
+    if (addr == NULL)
+        return -1;
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        ret = netxen_niu_macaddr_get(adapter, phy,
+                         (netxen_ethernet_macaddr_t *) *
+                         addr);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+               netxen_nic_driver_name, __FUNCTION__);
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int netxen_nic_set_mtu(struct netxen_port *port, int new_mtu)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    int ret = 0;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        netxen_nic_write_w0(adapter,
+                    NETXEN_NIU_GB_MAX_FRAME_SIZE(port->portnum),
+                    new_mtu);
+
+        break;
+
+    case NETXEN_NIC_XGBE:
+        new_mtu += 100;    /* so that MAC accepts frames > MTU */
+        netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
+                    new_mtu);
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int netxen_nic_set_promisc_mode(struct netxen_port *port)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    int phy = port->portnum;
+    int ret = 0;
+
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        ret = netxen_niu_set_promiscuous_mode(adapter, phy,
+                              NETXEN_NIU_PROMISCOUS_MODE);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        ret = netxen_niu_xg_set_promiscuous_mode(adapter, phy,
+                             NETXEN_NIU_PROMISCOUS_MODE);
+
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+int netxen_nic_unset_promisc_mode(struct netxen_port *port)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    int phy = port->portnum;
+    int ret = 0;
+
+    if ((phy < 0) || (phy > 3))
+        return -1;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        ret = netxen_niu_set_promiscuous_mode(adapter, phy,
+                              NETXEN_NIU_NON_PROMISCOUS_MODE);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        ret = netxen_niu_xg_set_promiscuous_mode(adapter, phy,
+                             NETXEN_NIU_NON_PROMISCOUS_MODE);
+
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }

1) two functions for such a simple task is overkill

2) just create separate hooks for GBE and XGBE, and eliminate these wrapper functions that do nothing but "switch (adapter->ahw.board_type)" before calling board-specific functions.


+long
+netxen_nic_phy_read(struct netxen_adapter *adapter, long phy, long reg,
+            u32 * readval)
+{
+    long ret = 0;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        ret = netxen_niu_gbe_phy_read(adapter, phy, reg, readval);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+               netxen_nic_driver_name, __FUNCTION__);
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+long netxen_nic_phy_write(struct netxen_adapter *adapter, long phy, long reg,
+              u32 val)
+{
+    long ret = 0;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        ret = netxen_niu_gbe_phy_write(adapter, phy, reg, val);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        printk(KERN_ERR "%s: Function %s is not implemented for XG\n",
+               netxen_nic_driver_name, __FUNCTION__);
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+long netxen_nic_init_port(struct netxen_port *port)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    long portnum = port->portnum;
+    long ret = 0;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        netxen_nic_disable_phy_interrupts(adapter, portnum);
+        udelay(20000);

NAK!!  It is unacceptable to spin the CPU for so long.


+        netxen_niu_gbe_init_port(adapter, portnum);
+
+        break;
+
+    case NETXEN_NIC_XGBE:
+        /* Nothing to be done for XG */
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+        ret = -1;
+    }
+
+    return ret;
+}
+
+void netxen_nic_init_niu(struct netxen_adapter *adapter)
+{
+    int portno;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        for (portno = 0; portno < NETXEN_NIU_MAX_GBE_PORTS; portno++)
+            netxen_niu_gbe_init_port(adapter, portno);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        /* Do nothing */
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+    }
+}
+
+void netxen_nic_stop_port(struct netxen_port *port)
+{
+    long portnum = port->portnum;
+    struct netxen_adapter *adapter = port->adapter;
+
+    switch (adapter->ahw.board_type) {
+    case NETXEN_NIC_GBE:
+        netxen_niu_disable_gbe_port(adapter, portnum);
+        break;
+
+    case NETXEN_NIC_XGBE:
+        netxen_niu_disable_xg_port(adapter, portnum);
+        break;
+
+    default:
+        printk(KERN_ERR "%s: Unknown board type\n",
+               netxen_nic_driver_name);
+    }
+}
+
+void netxen_nic_stop_all_ports(struct netxen_adapter *adapter)
+{
+    int port_nr;
+    struct netxen_port *port;
+
+    for (port_nr = 0; port_nr < adapter->ahw.max_ports; port_nr++) {
+        port = adapter->port[port_nr];
+        netxen_nic_stop_port(port);
+    }
+}
+
+void
+netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off,
+                int data)
+{
+    unsigned long flags;
+    void *addr;
+
+    if (ADDR_IN_WINDOW1(off)) {
+        read_lock(&adapter->adapter_lock);
+        writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
+        read_unlock(&adapter->adapter_lock);
+    } else {
+        write_lock_irqsave(&adapter->adapter_lock, flags);
+        netxen_nic_pci_change_crbwindow(adapter, 0);
+        addr = (void *)(adapter->ahw.pci_base + off);
+        writel(data, addr);
+        netxen_nic_pci_change_crbwindow(adapter, 1);
+        write_unlock_irqrestore(&adapter->adapter_lock, flags);
+    }
+}
+
+void netxen_nic_set_link_parameters(struct netxen_port *port)
+{
+    struct netxen_adapter *adapter = port->adapter;
+    struct netxen_niu_phy_status status;
+    u16 autoneg;
+    struct netxen_niu_control mode;
+
+    netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, (u32 *) & mode);
+    if (mode.enable_ge) {    /* Gb 10/100/1000 Mbps mode */
+        if (netxen_nic_phy_read(port->adapter, port->portnum,
+                    NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
+                    (netxen_crbword_t *) & status) == 0) {
+            if (status.link) {
+                switch (status.speed) {
+                case 0:
+                    port->link_speed = SPEED_10;
+                    break;
+                case 1:
+                    port->link_speed = SPEED_100;
+                    break;
+                case 2:
+                    port->link_speed = SPEED_1000;
+                    break;
+                default:
+                    port->link_speed = -1;    /* unknown speed */
+                    break;
+                }
+                switch (status.duplex) {
+                case 0:
+                    port->link_duplex = DUPLEX_HALF;
+                    break;
+                case 1:
+                    port->link_duplex = DUPLEX_FULL;
+                    break;
+                default:
+                    port->link_duplex = -1;    /* unknown mode */
+                    break;
+                }
+                if (netxen_nic_phy_read(port->adapter,
+                            port->portnum,
+                            NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
+                            (netxen_crbword_t *) &
+                            autoneg) != 0)
+                    port->link_autoneg = autoneg;
+            } else
+                goto link_down;
+        } else {
+              link_down:
+            port->link_speed = -1;
+            port->link_duplex = -1;
+        }
+    }
+}
+
+void netxen_nic_flash_print(struct netxen_adapter *adapter)
+{
+    int valid = 1;
+    u32 fw_major = 0;
+    u32 fw_minor = 0;
+    u32 fw_build = 0;
+
+    struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
+    if (board_info->magic != NETXEN_BDINFO_MAGIC) {
+        printk
+            ("NetXen Unknown board config, Read 0x%x expected as 0x%x\n",
+             board_info->magic, NETXEN_BDINFO_MAGIC);
+        valid = 0;
+    }
+    if (board_info->header_version != NETXEN_BDINFO_VERSION) {
+        printk("NetXen Unknown board config version."
+               " Read %x, expected %x\n",
+               board_info->header_version, NETXEN_BDINFO_VERSION);
+        valid = 0;
+    }
+    if (valid) {
+        printk("NetXen %s Board #%d, Chip id 0x%x\n",
+               board_info->board_type == 0x0b ? "XGB" : "GBE",
+               board_info->board_num, board_info->chip_id);
+        read_lock(&adapter->adapter_lock);
+        fw_major = readl(NETXEN_CRB_NORMALIZE(adapter,
+                              NETXEN_FW_VERSION_MAJOR));
+        fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter,
+                              NETXEN_FW_VERSION_MINOR));
+        fw_build =
+            readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB));
+        read_unlock(&adapter->adapter_lock);
+
+        printk("NetXen Firmware version %d.%d.%d\n", fw_major, fw_minor,
+               fw_build);
+    }
+    if (fw_major != _NETXEN_NIC_LINUX_MAJOR) {
+        printk(KERN_ERR "The mismatch in driver version and firmware "
+               "version major number\n"
+               "Driver version major number = %d \t"
+               "Firmware version major number = %d \n",
+               _NETXEN_NIC_LINUX_MAJOR, fw_major);
+        adapter->driver_mismatch = 1;
+    }
+    if (fw_minor != _NETXEN_NIC_LINUX_MINOR) {
+        printk(KERN_ERR "The mismatch in driver version and firmware "
+               "version minor number\n"
+               "Driver version minor number = %d \t"
+               "Firmware version minor number = %d \n",
+               _NETXEN_NIC_LINUX_MINOR, fw_minor);
+        adapter->driver_mismatch = 1;
+    }
+    if (adapter->driver_mismatch)
+        printk(KERN_INFO "Use the driver with version no %d.%d.xxx\n",
+               fw_major, fw_minor);
+}

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to