找回密码
 立即注册
img_loading
智能检测中

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888广告投放联系QQ68610888
glinet
查看: 5881|回复: 16

i211i210双网卡,i211不识别,启动提示The NVM Checksum Is Not Valid

[复制链接]
发表于 2021-4-15 22:19 | 显示全部楼层 |阅读模式
本帖最后由 spplove88 于 2021-4-16 07:06 编辑

openwrt
i211i210双网卡,i211不识别,只有eth0,在ifcong下只有一个ent0网卡还有一个lo网卡哪位大神能帮忙解决下。感谢!!
从新刷过网卡固件,主板bios。改mac地址都不行!爱快可以正常识别双网卡,exsi和乌班图都不能识别双网卡,都是能看到pci设备。
lspci能看到211pci设备

eth0      Link encap:Ethernet  HWaddr 00:19:7D:3E:A6:11  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8059 errors:0 dropped:5 overruns:0 frame:0
          TX packets:7376 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1049054 (1.0 MiB)  TX bytes:5342281 (5.0 MiB)
          Memory:fe800000-fe8fffff

lo        Link encapocal Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:4211 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4211 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:284575 (277.9 KiB)  TX bytes:284575 (277.9 KiB)

下面是启动时报的错误。
[   12.327071] igb 0000:01:00.0: eth0: PBA No: 000300-000
[   12.332278] igb 0000:01:00.0: Using MSI-X interrupts. 4 rx queue(s), 4 tx queue(s)
[   12.351788] igb 0000:02:00.0: The NVM Checksum Is Not Valid
[   12.431734] igb: probe of 0000:02:00.0 failed with error -5



熬了3天夜了都没解决。找到一个办法就是驱动里e1000-210.c文件删除以下代码在安装驱动。但是不知怎么操作。
for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
                ret_val = e1000_read_nvm(hw, i, 1, &nvm_data);
                if (ret_val) {
                        e_dbg("NVM Read Error\n");
                        return ret_val;
                }
                checksum += nvm_data;
        }

        if (checksum != (u16)NVM_SUM) {
                e_dbg("NVM Checksum Invalid\n");
                return -E1000_ERR_NVM;
        }







只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
发表于 2021-4-15 22:40 | 显示全部楼层
估计没有人能看懂你要表达什么
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2021-4-15 22:41 | 显示全部楼层
本帖最后由 badcrazy 于 2021-4-15 22:50 编辑

没头没脑这么问 你也不说下是什么系统,i211不被服务器系统识别很正常,比如winserver就不支持211,要装210驱动,既然你会刷网卡不如把211刷成210,不会不稳定的
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2021-4-15 23:13 | 显示全部楼层
本帖最后由 wulishui 于 2021-4-15 23:24 编辑

我看了些文档,是驱动过老不兼容引起的。如果你是自己编译系统,好办得很。否则要么自己思考编译,要么求人编译,要么扔掉。

点评

自己编译怎么操作。谢谢  详情 回复 发表于 2021-4-16 06:44
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-16 06:44 | 显示全部楼层
wulishui 发表于 2021-4-15 23:13
我看了些文档,是驱动过老不兼容引起的。如果你是自己编译系统,好办得很。否则要么自己思考编译,要么求人 ...

自己编译怎么操作。谢谢
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-20 10:03 | 显示全部楼层
问题勉强解决了。esxi重新封装的驱动。然后虚拟机安装lede。的。

点评

不会网卡驱动注入  详情 回复 发表于 2023-1-10 18:01
楼主好人,esxi重新封装的驱动能不能发往往一份398141365@qq,com  详情 回复 发表于 2023-1-10 18:00
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-20 10:05 | 显示全部楼层
跑满500兆CPU虚拟机下占用不到40高不高。
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-7-30 22:48 | 显示全部楼层
我是I210 3口,一个口都找不到,好长时间了,不知道什么原因
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-8-4 22:50 | 显示全部楼层
我的搞定了,


[code]// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2007 - 2018 Intel Corporation. */

/* e1000_i210
* e1000_i211
*/

#include <linux/types.h>
#include <linux/if_ether.h>

#include "e1000_hw.h"
#include "e1000_i210.h"

static s32 igb_update_flash_i210(struct e1000_hw *hw);

/**
* igb_get_hw_semaphore_i210 - Acquire hardware semaphore
*  @hw: pointer to the HW structure
*
*  Acquire the HW semaphore to access the PHY or NVM
*/
static s32 igb_get_hw_semaphore_i210(struct e1000_hw *hw)
{
        u32 swsm;
        s32 timeout = hw->nvm.word_size + 1;
        s32 i = 0;

        /* Get the SW semaphore */
        while (i < timeout) {
                swsm = rd32(E1000_SWSM);
                if (!(swsm & E1000_SWSM_SMBI))
                        break;

                udelay(50);
                i++;
        }

        if (i == timeout) {
                /* In rare circumstances, the SW semaphore may already be held
                 * unintentionally. Clear the semaphore once before giving up.
                 */
                if (hw->dev_spec._82575.clear_semaphore_once) {
                        hw->dev_spec._82575.clear_semaphore_once = false;
                        igb_put_hw_semaphore(hw);
                        for (i = 0; i < timeout; i++) {
                                swsm = rd32(E1000_SWSM);
                                if (!(swsm & E1000_SWSM_SMBI))
                                        break;

                                udelay(50);
                        }
                }

                /* If we do not have the semaphore here, we have to give up. */
                if (i == timeout) {
                        hw_dbg("Driver can't access device - SMBI bit is set.\n");
                        return -E1000_ERR_NVM;
                }
        }

        /* Get the FW semaphore. */
        for (i = 0; i < timeout; i++) {
                swsm = rd32(E1000_SWSM);
                wr32(E1000_SWSM, swsm | E1000_SWSM_SWESMBI);

                /* Semaphore acquired if bit latched */
                if (rd32(E1000_SWSM) & E1000_SWSM_SWESMBI)
                        break;

                udelay(50);
        }

        if (i == timeout) {
                /* Release semaphores */
                igb_put_hw_semaphore(hw);
                hw_dbg("Driver can't access the NVM\n");
                return -E1000_ERR_NVM;
        }

        return 0;
}

/**
*  igb_acquire_nvm_i210 - Request for access to EEPROM
*  @hw: pointer to the HW structure
*
*  Acquire the necessary semaphores for exclusive access to the EEPROM.
*  Set the EEPROM access request bit and wait for EEPROM access grant bit.
*  Return successful if access grant bit set, else clear the request for
*  EEPROM access and return -E1000_ERR_NVM (-1).
**/
static s32 igb_acquire_nvm_i210(struct e1000_hw *hw)
{
        return igb_acquire_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}

/**
*  igb_release_nvm_i210 - Release exclusive access to EEPROM
*  @hw: pointer to the HW structure
*
*  Stop any current commands to the EEPROM and clear the EEPROM request bit,
*  then release the semaphores acquired.
**/
static void igb_release_nvm_i210(struct e1000_hw *hw)
{
        igb_release_swfw_sync_i210(hw, E1000_SWFW_EEP_SM);
}

/**
*  igb_acquire_swfw_sync_i210 - Acquire SW/FW semaphore
*  @hw: pointer to the HW structure
*  @mask: specifies which semaphore to acquire
*
*  Acquire the SW/FW semaphore to access the PHY or NVM.  The mask
*  will also specify which port we're acquiring the lock for.
**/
s32 igb_acquire_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
        u32 swfw_sync;
        u32 swmask = mask;
        u32 fwmask = mask << 16;
        s32 ret_val = 0;
        s32 i = 0, timeout = 200; /* FIXME: find real value to use here */

        while (i < timeout) {
                if (igb_get_hw_semaphore_i210(hw)) {
                        ret_val = -E1000_ERR_SWFW_SYNC;
                        goto out;
                }

                swfw_sync = rd32(E1000_SW_FW_SYNC);
                if (!(swfw_sync & (fwmask | swmask)))
                        break;

                /* Firmware currently using resource (fwmask) */
                igb_put_hw_semaphore(hw);
                mdelay(5);
                i++;
        }

        if (i == timeout) {
                hw_dbg("Driver can't access resource, SW_FW_SYNC timeout.\n");
                ret_val = -E1000_ERR_SWFW_SYNC;
                goto out;
        }

        swfw_sync |= swmask;
        wr32(E1000_SW_FW_SYNC, swfw_sync);

        igb_put_hw_semaphore(hw);
out:
        return ret_val;
}

/**
*  igb_release_swfw_sync_i210 - Release SW/FW semaphore
*  @hw: pointer to the HW structure
*  @mask: specifies which semaphore to acquire
*
*  Release the SW/FW semaphore used to access the PHY or NVM.  The mask
*  will also specify which port we're releasing the lock for.
**/
void igb_release_swfw_sync_i210(struct e1000_hw *hw, u16 mask)
{
        u32 swfw_sync;

        while (igb_get_hw_semaphore_i210(hw))
                ; /* Empty */

        swfw_sync = rd32(E1000_SW_FW_SYNC);
        swfw_sync &= ~mask;
        wr32(E1000_SW_FW_SYNC, swfw_sync);

        igb_put_hw_semaphore(hw);
}

/**
*  igb_read_nvm_srrd_i210 - Reads Shadow Ram using EERD register
*  @hw: pointer to the HW structure
*  @offset: offset of word in the Shadow Ram to read
*  @words: number of words to read
*  @data: word read from the Shadow Ram
*
*  Reads a 16 bit word from the Shadow Ram using the EERD register.
*  Uses necessary synchronization semaphores.
**/
static s32 igb_read_nvm_srrd_i210(struct e1000_hw *hw, u16 offset, u16 words,
                                  u16 *data)
{
        s32 status = 0;
        u16 i, count;

        /* We cannot hold synchronization semaphores for too long,
         * because of forceful takeover procedure. However it is more efficient
         * to read in bursts than synchronizing access for each word.
         */
        for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
                count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
                        E1000_EERD_EEWR_MAX_COUNT : (words - i);
                if (!(hw->nvm.ops.acquire(hw))) {
                        status = igb_read_nvm_eerd(hw, offset, count,
                                                     data + i);
                        hw->nvm.ops.release(hw);
                } else {
                        status = E1000_ERR_SWFW_SYNC;
                }

                if (status)
                        break;
        }

        return status;
}

/**
*  igb_write_nvm_srwr - Write to Shadow Ram using EEWR
*  @hw: pointer to the HW structure
*  @offset: offset within the Shadow Ram to be written to
*  @words: number of words to write
*  @data: 16 bit word(s) to be written to the Shadow Ram
*
*  Writes data to Shadow Ram at offset using EEWR register.
*
*  If igb_update_nvm_checksum is not called after this function , the
*  Shadow Ram will most likely contain an invalid checksum.
**/
static s32 igb_write_nvm_srwr(struct e1000_hw *hw, u16 offset, u16 words,
                                u16 *data)
{
        struct e1000_nvm_info *nvm = &hw->nvm;
        u32 i, k, eewr = 0;
        u32 attempts = 100000;
        s32 ret_val = 0;

        /* A check for invalid values:  offset too large, too many words,
         * too many words for the offset, and not enough words.
         */
        if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
            (words == 0)) {
                hw_dbg("nvm parameter(s) out of bounds\n");
                ret_val = -E1000_ERR_NVM;
                goto out;
        }

        for (i = 0; i < words; i++) {
                eewr = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
                        (data[i] << E1000_NVM_RW_REG_DATA) |
                        E1000_NVM_RW_REG_START;

                wr32(E1000_SRWR, eewr);

                for (k = 0; k < attempts; k++) {
                        if (E1000_NVM_RW_REG_DONE &
                            rd32(E1000_SRWR)) {
                                ret_val = 0;
                                break;
                        }
                        udelay(5);
        }

                if (ret_val) {
                        hw_dbg("Shadow RAM write EEWR timed out\n");
                        break;
                }
        }

out:
        return ret_val;
}

/**
*  igb_write_nvm_srwr_i210 - Write to Shadow RAM using EEWR
*  @hw: pointer to the HW structure
*  @offset: offset within the Shadow RAM to be written to
*  @words: number of words to write
*  @data: 16 bit word(s) to be written to the Shadow RAM
*
*  Writes data to Shadow RAM at offset using EEWR register.
*
*  If e1000_update_nvm_checksum is not called after this function , the
*  data will not be committed to FLASH and also Shadow RAM will most likely
*  contain an invalid checksum.
*
*  If error code is returned, data and Shadow RAM may be inconsistent - buffer
*  partially written.
**/
static s32 igb_write_nvm_srwr_i210(struct e1000_hw *hw, u16 offset, u16 words,
                                   u16 *data)
{
        s32 status = 0;
        u16 i, count;

        /* We cannot hold synchronization semaphores for too long,
         * because of forceful takeover procedure. However it is more efficient
         * to write in bursts than synchronizing access for each word.
         */
        for (i = 0; i < words; i += E1000_EERD_EEWR_MAX_COUNT) {
                count = (words - i) / E1000_EERD_EEWR_MAX_COUNT > 0 ?
                        E1000_EERD_EEWR_MAX_COUNT : (words - i);
                if (!(hw->nvm.ops.acquire(hw))) {
                        status = igb_write_nvm_srwr(hw, offset, count,
                                                      data + i);
                        hw->nvm.ops.release(hw);
                } else {
                        status = E1000_ERR_SWFW_SYNC;
                }

                if (status)
                        break;
        }

        return status;
}

/**
*  igb_read_invm_word_i210 - Reads OTP
*  @hw: pointer to the HW structure
*  @address: the word address (aka eeprom offset) to read
*  @data: pointer to the data read
*
*  Reads 16-bit words from the OTP. Return error when the word is not
*  stored in OTP.
**/
static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
{
        s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
        u32 invm_dword;
        u16 i;
        u8 record_type, word_address;

        for (i = 0; i < E1000_INVM_SIZE; i++) {
                invm_dword = rd32(E1000_INVM_DATA_REG(i));
                /* Get record type */
                record_type = INVM_DWORD_TO_RECORD_TYPE(invm_dword);
                if (record_type == E1000_INVM_UNINITIALIZED_STRUCTURE)
                        break;
                if (record_type == E1000_INVM_CSR_AUTOLOAD_STRUCTURE)
                        i += E1000_INVM_CSR_AUTOLOAD_DATA_SIZE_IN_DWORDS;
                if (record_type == E1000_INVM_RSA_KEY_SHA256_STRUCTURE)
                        i += E1000_INVM_RSA_KEY_SHA256_DATA_SIZE_IN_DWORDS;
                if (record_type == E1000_INVM_WORD_AUTOLOAD_STRUCTURE) {
                        word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
                        if (word_address == address) {
                                *data = INVM_DWORD_TO_WORD_DATA(invm_dword);
                                hw_dbg("Read INVM Word 0x%02x = %x\n",
                                          address, *data);
                                status = 0;
                                break;
                        }
                }
        }
        if (status)
                hw_dbg("Requested word 0x%02x not found in OTP\n", address);
        return status;
}

/**
* igb_read_invm_i210 - Read invm wrapper function for I210/I211
*  @hw: pointer to the HW structure
*  @offset: offset to read from
*  @words: number of words to read (unused)
*  @data: pointer to the data read
*
*  Wrapper function to return data formerly found in the NVM.
**/
static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
                                u16 __always_unused words, u16 *data)
{
        s32 ret_val = 0;

        /* Only the MAC addr is required to be present in the iNVM */
        switch (offset) {
        case NVM_MAC_ADDR:
                ret_val = igb_read_invm_word_i210(hw, (u8)offset, &data[0]);
                ret_val |= igb_read_invm_word_i210(hw, (u8)offset+1,
                                                     &data[1]);
                ret_val |= igb_read_invm_word_i210(hw, (u8)offset+2,
                                                     &data[2]);
                if (ret_val)
                        hw_dbg("MAC Addr not found in iNVM\n");
                break;
        case NVM_INIT_CTRL_2:
                ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
                if (ret_val) {
                        *data = NVM_INIT_CTRL_2_DEFAULT_I211;
                        ret_val = 0;
                }
                break;
        case NVM_INIT_CTRL_4:
                ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
                if (ret_val) {
                        *data = NVM_INIT_CTRL_4_DEFAULT_I211;
                        ret_val = 0;
                }
                break;
        case NVM_LED_1_CFG:
                ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
                if (ret_val) {
                        *data = NVM_LED_1_CFG_DEFAULT_I211;
                        ret_val = 0;
                }
                break;
        case NVM_LED_0_2_CFG:
                ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
                if (ret_val) {
                        *data = NVM_LED_0_2_CFG_DEFAULT_I211;
                        ret_val = 0;
                }
                break;
        case NVM_ID_LED_SETTINGS:
                ret_val = igb_read_invm_word_i210(hw, (u8)offset, data);
                if (ret_val) {
                        *data = ID_LED_RESERVED_FFFF;
                        ret_val = 0;
                }
                break;
        case NVM_SUB_DEV_ID:
                *data = hw->subsystem_device_id;
                break;
        case NVM_SUB_VEN_ID:
                *data = hw->subsystem_vendor_id;
                break;
        case NVM_DEV_ID:
                *data = hw->device_id;
                break;
        case NVM_VEN_ID:
                *data = hw->vendor_id;
                break;
        default:
                hw_dbg("NVM word 0x%02x is not mapped.\n", offset);
                *data = NVM_RESERVED_WORD;
                break;
        }
        return ret_val;
}

/**
*  igb_read_invm_version - Reads iNVM version and image type
*  @hw: pointer to the HW structure
*  @invm_ver: version structure for the version read
*
*  Reads iNVM version and image type.
**/
s32 igb_read_invm_version(struct e1000_hw *hw,
                          struct e1000_fw_version *invm_ver) {
        u32 *record = NULL;
        u32 *next_record = NULL;
        u32 i = 0;
        u32 invm_dword = 0;
        u32 invm_blocks = E1000_INVM_SIZE - (E1000_INVM_ULT_BYTES_SIZE /
                                             E1000_INVM_RECORD_SIZE_IN_BYTES);
        u32 buffer[E1000_INVM_SIZE];
        s32 status = -E1000_ERR_INVM_VALUE_NOT_FOUND;
        u16 version = 0;

        /* Read iNVM memory */
        for (i = 0; i < E1000_INVM_SIZE; i++) {
                invm_dword = rd32(E1000_INVM_DATA_REG(i));
                buffer[i] = invm_dword;
        }

        /* Read version number */
        for (i = 1; i < invm_blocks; i++) {
                record = &buffer[invm_blocks - i];
                next_record = &buffer[invm_blocks - i + 1];

                /* Check if we have first version location used */
                if ((i == 1) && ((*record & E1000_INVM_VER_FIELD_ONE) == 0)) {
                        version = 0;
                        status = 0;
                        break;
                }
                /* Check if we have second version location used */
                else if ((i == 1) &&
                         ((*record & E1000_INVM_VER_FIELD_TWO) == 0)) {
                        version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
                        status = 0;
                        break;
                }
                /* Check if we have odd version location
                 * used and it is the last one used
                 */
                else if ((((*record & E1000_INVM_VER_FIELD_ONE) == 0) &&
                         ((*record & 0x3) == 0)) || (((*record & 0x3) != 0) &&
                         (i != 1))) {
                        version = (*next_record & E1000_INVM_VER_FIELD_TWO)
                                  >> 13;
                        status = 0;
                        break;
                }
                /* Check if we have even version location
                 * used and it is the last one used
                 */
                else if (((*record & E1000_INVM_VER_FIELD_TWO) == 0) &&
                         ((*record & 0x3) == 0)) {
                        version = (*record & E1000_INVM_VER_FIELD_ONE) >> 3;
                        status = 0;
                        break;
                }
        }

        if (!status) {
                invm_ver->invm_major = (version & E1000_INVM_MAJOR_MASK)
                                        >> E1000_INVM_MAJOR_SHIFT;
                invm_ver->invm_minor = version & E1000_INVM_MINOR_MASK;
        }
        /* Read Image Type */
        for (i = 1; i < invm_blocks; i++) {
                record = &buffer[invm_blocks - i];
                next_record = &buffer[invm_blocks - i + 1];

                /* Check if we have image type in first location used */
                if ((i == 1) && ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) {
                        invm_ver->invm_img_type = 0;
                        status = 0;
                        break;
                }
                /* Check if we have image type in first location used */
                else if ((((*record & 0x3) == 0) &&
                         ((*record & E1000_INVM_IMGTYPE_FIELD) == 0)) ||
                         ((((*record & 0x3) != 0) && (i != 1)))) {
                        invm_ver->invm_img_type =
                                (*next_record & E1000_INVM_IMGTYPE_FIELD) >> 23;
                        status = 0;
                        break;
                }
        }
        return status;
}

/**
*  igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
*  @hw: pointer to the HW structure
*
*  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
*  and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
static s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
{
        s32 status = 0;
        s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);

        return 0;
}

/**
*  igb_update_nvm_checksum_i210 - Update EEPROM checksum
*  @hw: pointer to the HW structure
*
*  Updates the EEPROM checksum by reading/adding each word of the EEPROM
*  up to the checksum.  Then calculates the EEPROM checksum and writes the
*  value to the EEPROM. Next commit EEPROM data onto the Flash.
**/
static s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
{
        s32 ret_val = 0;
        u16 checksum = 0;
        u16 i, nvm_data;

        return 0;
}

/**
*  igb_pool_flash_update_done_i210 - Pool FLUDONE status.
*  @hw: pointer to the HW structure
*
**/
static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
{
        s32 ret_val = -E1000_ERR_NVM;
        u32 i, reg;

        return 0;
}

/**
*  igb_get_flash_presence_i210 - Check if flash device is detected.
*  @hw: pointer to the HW structure
*
**/
bool igb_get_flash_presence_i210(struct e1000_hw *hw)
{
        u32 eec = 0;
        bool ret_val = false;

        eec = rd32(E1000_EECD);
        if (eec & E1000_EECD_FLASH_DETECTED_I210)
                ret_val = true;

        return ret_val;
}

/**
*  igb_update_flash_i210 - Commit EEPROM to the flash
*  @hw: pointer to the HW structure
*
**/
static s32 igb_update_flash_i210(struct e1000_hw *hw)
{
        s32 ret_val = 0;
        u32 flup;

        ret_val = igb_pool_flash_update_done_i210(hw);
       
        return 0;
}

/**
*  igb_valid_led_default_i210 - Verify a valid default LED config
*  @hw: pointer to the HW structure
*  @data: pointer to the NVM (EEPROM)
*
*  Read the EEPROM for the current default LED configuration.  If the
*  LED configuration is not valid, set to a valid LED configuration.
**/
s32 igb_valid_led_default_i210(struct e1000_hw *hw, u16 *data)
{
        s32 ret_val;

        return 0;
}

/**
*  __igb_access_xmdio_reg - Read/write XMDIO register
*  @hw: pointer to the HW structure
*  @address: XMDIO address to program
*  @dev_addr: device address to program
*  @data: pointer to value to read/write from/to the XMDIO address
*  @read: boolean flag to indicate read or write
**/
static s32 __igb_access_xmdio_reg(struct e1000_hw *hw, u16 address,
                                  u8 dev_addr, u16 *data, bool read)
{
        s32 ret_val = 0;

        ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, dev_addr);
        if (ret_val)
                return ret_val;

        ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, address);
        if (ret_val)
                return ret_val;

        ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, E1000_MMDAC_FUNC_DATA |
                                                         dev_addr);
        if (ret_val)
                return ret_val;

        if (read)
                ret_val = hw->phy.ops.read_reg(hw, E1000_MMDAAD, data);
        else
                ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAAD, *data);
        if (ret_val)
                return ret_val;

        /* Recalibrate the device back to 0 */
        ret_val = hw->phy.ops.write_reg(hw, E1000_MMDAC, 0);
        if (ret_val)
                return ret_val;

        return ret_val;
}

/**
*  igb_read_xmdio_reg - Read XMDIO register
*  @hw: pointer to the HW structure
*  @addr: XMDIO address to program
*  @dev_addr: device address to program
*  @data: value to be read from the EMI address
**/
s32 igb_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 *data)
{
        return __igb_access_xmdio_reg(hw, addr, dev_addr, data, true);
}

/**
*  igb_write_xmdio_reg - Write XMDIO register
*  @hw: pointer to the HW structure
*  @addr: XMDIO address to program
*  @dev_addr: device address to program
*  @data: value to be written to the XMDIO address
**/
s32 igb_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
{
        return __igb_access_xmdio_reg(hw, addr, dev_addr, &data, false);
}

/**
*  igb_init_nvm_params_i210 - Init NVM func ptrs.
*  @hw: pointer to the HW structure
**/
s32 igb_init_nvm_params_i210(struct e1000_hw *hw)
{
        s32 ret_val = 0;
        struct e1000_nvm_info *nvm = &hw->nvm;

        nvm->ops.acquire = igb_acquire_nvm_i210;
        nvm->ops.release = igb_release_nvm_i210;
        nvm->ops.valid_led_default = igb_valid_led_default_i210;

        /* NVM Function Pointers */
        if (igb_get_flash_presence_i210(hw)) {
                hw->nvm.type = e1000_nvm_flash_hw;
                nvm->ops.read    = igb_read_nvm_srrd_i210;
                nvm->ops.write   = igb_write_nvm_srwr_i210;
                nvm->ops.validate = igb_validate_nvm_checksum_i210;
                nvm->ops.update   = igb_update_nvm_checksum_i210;
        } else {
                hw->nvm.type = e1000_nvm_invm;
                nvm->ops.read     = igb_read_invm_i210;
                nvm->ops.write    = NULL;
                nvm->ops.validate = NULL;
                nvm->ops.update   = NULL;
        }
        return ret_val;
}

/**
* igb_pll_workaround_i210
* @hw: pointer to the HW structure
*
* Works around an errata in the PLL circuit where it occasionally
* provides the wrong clock frequency after power up.
**/
s32 igb_pll_workaround_i210(struct e1000_hw *hw)
{
        s32 ret_val;
        u32 wuc, mdicnfg, ctrl, ctrl_ext, reg_val;
        u16 nvm_word, phy_word, pci_word, tmp_nvm;
        int i;

        /* Get and set needed register values */
        wuc = rd32(E1000_WUC);
        mdicnfg = rd32(E1000_MDICNFG);
        reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
        wr32(E1000_MDICNFG, reg_val);

        /* Get data from NVM, or set default */
        ret_val = igb_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
                                          &nvm_word);
        if (ret_val)
                nvm_word = E1000_INVM_DEFAULT_AL;
        tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
        igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, E1000_PHY_PLL_FREQ_PAGE);
        phy_word = E1000_PHY_PLL_UNCONF;
        for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
                /* check current state directly from internal PHY */
                igb_read_phy_reg_82580(hw, E1000_PHY_PLL_FREQ_REG, &phy_word);
                if ((phy_word & E1000_PHY_PLL_UNCONF)
                    != E1000_PHY_PLL_UNCONF) {
                        ret_val = 0;
                        break;
                } else {
                        ret_val = -E1000_ERR_PHY;
                }
                /* directly reset the internal PHY */
                ctrl = rd32(E1000_CTRL);
                wr32(E1000_CTRL, ctrl|E1000_CTRL_PHY_RST);

                ctrl_ext = rd32(E1000_CTRL_EXT);
                ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
                wr32(E1000_CTRL_EXT, ctrl_ext);

                wr32(E1000_WUC, 0);
                reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
                wr32(E1000_EEARBC_I210, reg_val);

                igb_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
                pci_word |= E1000_PCI_PMCSR_D3;
                igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
                usleep_range(1000, 2000);
                pci_word &= ~E1000_PCI_PMCSR_D3;
                igb_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
                reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
                wr32(E1000_EEARBC_I210, reg_val);

                /* restore WUC register */
                wr32(E1000_WUC, wuc);
        }
        igb_write_phy_reg_82580(hw, I347AT4_PAGE_SELECT, 0);
        /* restore MDICNFG setting */
        wr32(E1000_MDICNFG, mdicnfg);
        return ret_val;
}

/**
*  igb_get_cfg_done_i210 - Read config done bit
*  @hw: pointer to the HW structure
*
*  Read the management control register for the config done bit for
*  completion status.  NOTE: silicon which is EEPROM-less will fail trying
*  to read the config done bit, so an error is *ONLY* logged and returns
*  0.  If we were to return with error, EEPROM-less silicon
*  would not be able to be reset or change link.
**/
s32 igb_get_cfg_done_i210(struct e1000_hw *hw)
{
        s32 timeout = PHY_CFG_TIMEOUT;
        u32 mask = E1000_NVM_CFG_DONE_PORT_0;

        while (timeout) {
                if (rd32(E1000_EEMNGCTL_I210) & mask)
                        break;
                usleep_range(1000, 2000);
                timeout--;
        }
        if (!timeout)
                hw_dbg("MNG configuration cycle has not completed.\n");

        return 0;
}
[


E1000驱动源代码,还有附件,覆盖lede目录下的
build_dir/target-x86_64_musl/linux-x86_64/linux-5.15.36/drivers/net/ethernet/intel/igb/e1000_i210.c
以及
build_dir/toolchain-x86_64_gcc-8.4.0_musl/linux-5.15.36/drivers/net/ethernet/intel/igb/e1000_i210.c


记得rm -rf ./tmp && rf .config

然后编译


make V=s -j1

祝你好运!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-8-5 16:08 | 显示全部楼层
/**
*  igb_validate_nvm_checksum_i210 - Validate EEPROM checksum
*  @hw: pointer to the HW structure
*
*  Calculates the EEPROM checksum by reading/adding each word of the EEPROM
*  and then verifies that the sum of the EEPROM is equal to 0xBABA.
**/
static s32 igb_validate_nvm_checksum_i210(struct e1000_hw *hw)
{
        s32 status = 0;
        s32 (*read_op_ptr)(struct e1000_hw *, u16, u16, u16 *);

        return 0;
}

/**
*  igb_update_nvm_checksum_i210 - Update EEPROM checksum
*  @hw: pointer to the HW structure
*
*  Updates the EEPROM checksum by reading/adding each word of the EEPROM
*  up to the checksum.  Then calculates the EEPROM checksum and writes the
*  value to the EEPROM. Next commit EEPROM data onto the Flash.
**/
static s32 igb_update_nvm_checksum_i210(struct e1000_hw *hw)
{
        s32 ret_val = 0;
        u16 checksum = 0;
        u16 i, nvm_data;

        return 0;
}

/**
*  igb_pool_flash_update_done_i210 - Pool FLUDONE status.
*  @hw: pointer to the HW structure
*
**/
static s32 igb_pool_flash_update_done_i210(struct e1000_hw *hw)
{
        s32 ret_val = -E1000_ERR_NVM;
        u32 i, reg;

        return 0;
}

/**
*  igb_get_flash_presence_i210 - Check if flash device is detected.
*  @hw: pointer to the HW structure
*
**/
bool igb_get_flash_presence_i210(struct e1000_hw *hw)
{
        u32 eec = 0;
        bool ret_val = false;

        eec = rd32(E1000_EECD);
        if (eec & E1000_EECD_FLASH_DETECTED_I210)
                ret_val = true;

        return ret_val;
}

/**
*  igb_update_flash_i210 - Commit EEPROM to the flash
*  @hw: pointer to the HW structure
*
**/
static s32 igb_update_flash_i210(struct e1000_hw *hw)
{
        s32 ret_val = 0;
        u32 flup;

        ret_val = igb_pool_flash_update_done_i210(hw);
       
        return 0;
}





只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-8-5 16:17 | 显示全部楼层
再附个e1000_i210.c
覆盖
lede/build_dir/target-x86_64_musl/linux-x86_64/linux-5.15.36/drivers/net/ethernet/intel/igb/e1000_i210.c

lede/build_dir/toolchain-x86_64_gcc-8.4.0_musl/linux-5.15.36/drivers/net/ethernet/intel/igb/e1000_i210.c

然后编译


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×

点评

aoling888@163。com。谢谢  详情 回复 发表于 2022-10-15 08:34
哥们,我也是三口I210网卡,刷了好多固件都不识别,你那有没有编译好的固件发我一个试试,我还从来没编译过固件  详情 回复 发表于 2022-10-15 08:28
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-10-15 08:28 | 显示全部楼层
lzf577 发表于 2022-8-5 16:17
再附个e1000_i210.c
覆盖
lede/build_dir/target-x86_64_musl/linux-x86_64/linux-5.15.36/drivers/net/ ...

哥们,我也是三口I210网卡,刷了好多固件都不识别,你那有没有编译好的固件发我一个试试,我还从来没编译过固件
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-10-15 08:34 | 显示全部楼层
350950537 发表于 2022-10-15 08:28
哥们,我也是三口I210网卡,刷了好多固件都不识别,你那有没有编译好的固件发我一个试试,我还从来没编译 ...

aoling888@163.com。。。。。。谢谢
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2022-10-15 08:34 | 显示全部楼层
lzf577 发表于 2022-8-5 16:17
再附个e1000_i210.c
覆盖
lede/build_dir/target-x86_64_musl/linux-x86_64/linux-5.15.36/drivers/net/ ...

aoling888@163。com。谢谢
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

发表于 2023-1-10 18:00 | 显示全部楼层
spplove88 发表于 2021-4-20 10:03
问题勉强解决了。esxi重新封装的驱动。然后虚拟机安装lede。的。

楼主好人,esxi重新封装的驱动能不能发往往一份398141365@qq,com
只谈技术、莫论政事!(点击见详情) | 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛

只谈技术、莫论政事!切勿转播谣言!为了你也为了他人。
只谈技术、莫论政事!(点击见详情) 切记不要随意传播谣言,把自己的日子过安稳了就行,为了自己好也为了大家好。 恩山无线论坛欢迎您的来访,请互相尊重、友善交流,建议保持一颗平常心看待网友的评论,切勿过度反应。

查看 »

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2025-5-17 16:00

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com

快速回复 返回顶部 返回列表