]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/netxen/netxen_nic_hw.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[linux-2.6-omap-h63xx.git] / drivers / net / netxen / netxen_nic_hw.c
index b564d69cfa457f6b6877aee4ff62aa2650b23ce2..5026811c04ced0a1d1d4effe7dc033c47d083dba 100644 (file)
@@ -515,7 +515,7 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
                        &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
 
                producer = get_next_index(producer,
-                               adapter->max_tx_desc_count);
+                               adapter->num_txd);
                i++;
 
        } while (i != nr_elements);
@@ -670,6 +670,53 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
        return rv;
 }
 
+#define RSS_HASHTYPE_IP_TCP    0x3
+
+int netxen_config_rss(struct netxen_adapter *adapter, int enable)
+{
+       nx_nic_req_t req;
+       u64 word;
+       int i, rv;
+
+       u64 key[] = { 0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
+                       0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
+                       0x255b0ec26d5a56daULL };
+
+
+       memset(&req, 0, sizeof(nx_nic_req_t));
+       req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+       word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
+       req.req_hdr = cpu_to_le64(word);
+
+       /*
+        * RSS request:
+        * bits 3-0: hash_method
+        *      5-4: hash_type_ipv4
+        *      7-6: hash_type_ipv6
+        *        8: enable
+        *        9: use indirection table
+        *    47-10: reserved
+        *    63-48: indirection table mask
+        */
+       word =  ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
+               ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
+               ((u64)(enable & 0x1) << 8) |
+               ((0x7ULL) << 48);
+       req.words[0] = cpu_to_le64(word);
+       for (i = 0; i < 5; i++)
+               req.words[i+1] = cpu_to_le64(key[i]);
+
+
+       rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+       if (rv != 0) {
+               printk(KERN_ERR "%s: could not configure RSS\n",
+                               adapter->netdev->name);
+       }
+
+       return rv;
+}
+
 /*
  * netxen_nic_change_mtu - Change the Maximum Transfer Unit
  * @returns 0 on success, negative on failure
@@ -703,34 +750,11 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
        return rc;
 }
 
-int netxen_is_flash_supported(struct netxen_adapter *adapter)
-{
-       const int locs[] = { 0, 0x4, 0x100, 0x4000, 0x4128 };
-       int addr, val01, val02, i, j;
-
-       /* if the flash size less than 4Mb, make huge war cry and die */
-       for (j = 1; j < 4; j++) {
-               addr = j * NETXEN_NIC_WINDOW_MARGIN;
-               for (i = 0; i < ARRAY_SIZE(locs); i++) {
-                       if (netxen_rom_fast_read(adapter, locs[i], &val01) == 0
-                           && netxen_rom_fast_read(adapter, (addr + locs[i]),
-                                                   &val02) == 0) {
-                               if (val01 == val02)
-                                       return -1;
-                       } else
-                               return -1;
-               }
-       }
-
-       return 0;
-}
-
 static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
                                  int size, __le32 * buf)
 {
-       int i, addr;
+       int i, v, addr;
        __le32 *ptr32;
-       u32 v;
 
        addr = base;
        ptr32 = buf;
@@ -1084,21 +1108,21 @@ netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
        return 0;
 }
 
+static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
+
 int netxen_load_firmware(struct netxen_adapter *adapter)
 {
        u32 capability, flashed_ver;
        const struct firmware *fw;
-       char *fw_name = NULL;
+       int fw_type;
        struct pci_dev *pdev = adapter->pdev;
        int rc = 0;
 
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-               fw_name = NX_P2_MN_ROMIMAGE;
+               fw_type = NX_P2_MN_ROMIMAGE;
                goto request_fw;
-       }
-
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-               fw_name = NX_P3_CT_ROMIMAGE;
+       } else {
+               fw_type = NX_P3_CT_ROMIMAGE;
                goto request_fw;
        }
 
@@ -1111,15 +1135,15 @@ request_mn:
                adapter->hw_read_wx(adapter,
                                NX_PEG_TUNE_CAPABILITY, &capability, 4);
                if (capability & NX_PEG_TUNE_MN_PRESENT) {
-                       fw_name = NX_P3_MN_ROMIMAGE;
+                       fw_type = NX_P3_MN_ROMIMAGE;
                        goto request_fw;
                }
        }
 
 request_fw:
-       rc = request_firmware(&fw, fw_name, &pdev->dev);
+       rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev);
        if (rc != 0) {
-               if (fw_name == NX_P3_CT_ROMIMAGE) {
+               if (fw_type == NX_P3_CT_ROMIMAGE) {
                        msleep(1);
                        goto request_mn;
                }
@@ -1128,11 +1152,11 @@ request_fw:
                goto load_fw;
        }
 
-       rc = netxen_validate_firmware(adapter, fw_name, fw);
+       rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw);
        if (rc != 0) {
                release_firmware(fw);
 
-               if (fw_name == NX_P3_CT_ROMIMAGE) {
+               if (fw_type == NX_P3_CT_ROMIMAGE) {
                        msleep(1);
                        goto request_mn;
                }
@@ -1141,7 +1165,7 @@ request_fw:
        }
 
 load_fw:
-       rc = netxen_do_load_firmware(adapter, fw_name, fw);
+       rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw);
 
        if (fw)
                release_firmware(fw);
@@ -2089,47 +2113,44 @@ u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 {
-       int rv = 0;
-       int addr = NETXEN_BRDCFG_START;
-       struct netxen_board_info *boardinfo;
-       int index;
-       int *ptr32;
+       int offset, board_type, magic, header_version;
+       struct pci_dev *pdev = adapter->pdev;
 
-       boardinfo = &adapter->ahw.boardcfg;
-       ptr32 = (int *) boardinfo;
+       offset = NETXEN_BRDCFG_START +
+               offsetof(struct netxen_board_info, magic);
+       if (netxen_rom_fast_read(adapter, offset, &magic))
+               return -EIO;
 
-       for (index = 0; index < sizeof(struct netxen_board_info) / sizeof(u32);
-            index++) {
-               if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
-                       return -EIO;
-               }
-               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;
+       offset = NETXEN_BRDCFG_START +
+               offsetof(struct netxen_board_info, header_version);
+       if (netxen_rom_fast_read(adapter, offset, &header_version))
+               return -EIO;
+
+       if (magic != NETXEN_BDINFO_MAGIC ||
+                       header_version != NETXEN_BDINFO_VERSION) {
+               dev_err(&pdev->dev,
+                       "invalid board config, magic=%08x, version=%08x\n",
+                       magic, header_version);
+               return -EIO;
        }
 
-       if (boardinfo->board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
+       offset = NETXEN_BRDCFG_START +
+               offsetof(struct netxen_board_info, board_type);
+       if (netxen_rom_fast_read(adapter, offset, &board_type))
+               return -EIO;
+
+       adapter->ahw.board_type = board_type;
+
+       if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
                u32 gpio = netxen_nic_reg_read(adapter,
                                NETXEN_ROMUSB_GLB_PAD_GPIO_I);
                if ((gpio & 0x8000) == 0)
-                       boardinfo->board_type = NETXEN_BRDTYPE_P3_10G_TP;
+                       board_type = NETXEN_BRDTYPE_P3_10G_TP;
        }
 
-       switch ((netxen_brdtype_t) boardinfo->board_type) {
+       switch ((netxen_brdtype_t)board_type) {
        case NETXEN_BRDTYPE_P2_SB35_4G:
-               adapter->ahw.board_type = NETXEN_NIC_GBE;
+               adapter->ahw.port_type = NETXEN_NIC_GBE;
                break;
        case NETXEN_BRDTYPE_P2_SB31_10G:
        case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
@@ -2145,7 +2166,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
        case NETXEN_BRDTYPE_P3_10G_SFP_QT:
        case NETXEN_BRDTYPE_P3_10G_XFP:
        case NETXEN_BRDTYPE_P3_10000_BASE_T:
-               adapter->ahw.board_type = NETXEN_NIC_XGBE;
+               adapter->ahw.port_type = NETXEN_NIC_XGBE;
                break;
        case NETXEN_BRDTYPE_P1_BD:
        case NETXEN_BRDTYPE_P1_SB:
@@ -2154,20 +2175,19 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
        case NETXEN_BRDTYPE_P3_REF_QG:
        case NETXEN_BRDTYPE_P3_4_GB:
        case NETXEN_BRDTYPE_P3_4_GB_MM:
-               adapter->ahw.board_type = NETXEN_NIC_GBE;
+               adapter->ahw.port_type = NETXEN_NIC_GBE;
                break;
        case NETXEN_BRDTYPE_P3_10G_TP:
-               adapter->ahw.board_type = (adapter->portnum < 2) ?
+               adapter->ahw.port_type = (adapter->portnum < 2) ?
                        NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
                break;
        default:
-               printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
-                      boardinfo->board_type);
-               rv = -ENODEV;
+               dev_err(&pdev->dev, "unknown board type %x\n", board_type);
+               adapter->ahw.port_type = NETXEN_NIC_XGBE;
                break;
        }
 
-       return rv;
+       return 0;
 }
 
 /* NIU access sections */
@@ -2213,7 +2233,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
                return;
        }
 
-       if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
+       if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
                adapter->hw_read_wx(adapter,
                                NETXEN_PORT_MODE_ADDR, &port_mode, 4);
                if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
@@ -2268,17 +2288,14 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
        }
 }
 
-void netxen_nic_flash_print(struct netxen_adapter *adapter)
+void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
 {
-       u32 fw_major = 0;
-       u32 fw_minor = 0;
-       u32 fw_build = 0;
+       u32 fw_major, fw_minor, fw_build;
        char brd_name[NETXEN_MAX_SHORT_NAME];
        char serial_num[32];
-       int i, addr;
+       int i, addr, val;
        int *ptr32;
-
-       struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
+       struct pci_dev *pdev = adapter->pdev;
 
        adapter->driver_mismatch = 0;
 
@@ -2286,14 +2303,12 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
        addr = NETXEN_USER_START +
               offsetof(struct netxen_new_user_info, serial_num);
        for (i = 0; i < 8; i++) {
-               if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
-                       printk("%s: ERROR reading %s board userarea.\n",
-                              netxen_nic_driver_name,
-                              netxen_nic_driver_name);
+               if (netxen_rom_fast_read(adapter, addr, &val) == -1) {
+                       dev_err(&pdev->dev, "error reading board info\n");
                        adapter->driver_mismatch = 1;
                        return;
                }
-               ptr32++;
+               ptr32[i] = cpu_to_le32(val);
                addr += sizeof(u32);
        }
 
@@ -2302,23 +2317,48 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
        adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
 
        adapter->fw_major = fw_major;
+       adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
 
        if (adapter->portnum == 0) {
-               get_brd_name_by_type(board_info->board_type, brd_name);
+               get_brd_name_by_type(adapter->ahw.board_type, brd_name);
 
                printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
                                brd_name, serial_num, adapter->ahw.revision_id);
-               printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
-                               fw_major, fw_minor, fw_build);
        }
 
-       if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
-                       NETXEN_VERSION_CODE(3, 4, 216)) {
+       if (adapter->fw_version < NETXEN_VERSION_CODE(3, 4, 216)) {
                adapter->driver_mismatch = 1;
-               printk(KERN_ERR "%s: firmware version %d.%d.%d unsupported\n",
-                               netxen_nic_driver_name,
+               dev_warn(&pdev->dev, "firmware version %d.%d.%d unsupported\n",
                                fw_major, fw_minor, fw_build);
                return;
        }
+
+       dev_info(&pdev->dev, "firmware version %d.%d.%d\n",
+                       fw_major, fw_minor, fw_build);
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+               adapter->hw_read_wx(adapter,
+                               NETXEN_MIU_MN_CONTROL, &i, 4);
+               adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
+               dev_info(&pdev->dev, "firmware running in %s mode\n",
+               adapter->ahw.cut_through ? "cut-through" : "legacy");
+       }
 }
 
+int
+netxen_nic_wol_supported(struct netxen_adapter *adapter)
+{
+       u32 wol_cfg;
+
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               return 0;
+
+       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       if (wol_cfg & (1UL << adapter->portnum)) {
+               wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+               if (wol_cfg & (1 << adapter->portnum))
+                       return 1;
+       }
+
+       return 0;
+}