Intel unsupported sfp: различия между версиями

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску
Строка 197: Строка 197:
 
}}
 
}}
   
==<code>3</code>==
+
==<code>xl710_unlock.c</code>==
{{#spoiler:show=1|
+
{{#spoiler:show=xl710_unlock.c|
   
 
<PRE>
 
<PRE>
  +
#include <stdint.h>
  +
#include <stdlib.h>
  +
#include <stdio.h>
  +
#include <string.h>
  +
#include <net/if.h>
  +
#include <sys/ioctl.h>
  +
#include <linux/sockios.h>
  +
#include <unistd.h>
  +
#include "syscalls.h"
  +
  +
  +
void die( const char *reason ) {
  +
perror( reason );
  +
exit( EXIT_FAILURE );
  +
}
  +
  +
void print_usage( void )
  +
{
  +
printf( "xl710_unlock\n" );
  +
printf( " -n <device_name>, required\n" );
  +
printf( " -i <device_id>, default: 0x1572\n" );
  +
printf( " -p lock/unlock\n" );
  +
  +
exit( EXIT_FAILURE );
  +
}
  +
  +
int main(int argc, char *const *argv) {
  +
/* Parse arguments */
  +
char *c_devid = "0x1572";
  +
char *c_devname = NULL;
  +
int patching = 0;
  +
  +
int c;
  +
  +
while( ( c = getopt( argc, argv, "i:n:h?" ) ) != -1 )
  +
{
  +
switch( c )
  +
{
  +
case 'i':
  +
c_devid = optarg;
  +
break;
  +
case 'n':
  +
c_devname = optarg;
  +
break;
  +
case 'h':
  +
case '?':
  +
default:
  +
print_usage();
  +
break;
  +
}
  +
}
  +
  +
if( c_devname == NULL ) print_usage();
  +
  +
int mod = 0;
  +
uint16_t length = 0x02;
  +
int fd;
  +
struct ifreq ifr;
  +
struct ethtool_eeprom *eeprom;
  +
  +
const int devid = strtol( c_devid, 0, 0 );
  +
const char *ethDev = c_devname;
  +
  +
fd = socket( AF_INET, SOCK_DGRAM, 0 );
  +
if( fd == -1 ) die( "socket" );
  +
  +
eeprom = calloc( 1, sizeof( *eeprom ) + ( length << 1 ) );
  +
if( !eeprom ) die( "calloc" );
  +
  +
eeprom->cmd = ETHTOOL_GEEPROM;
  +
eeprom->magic = (devid << 16) | (I40E_NVM_SA << I40E_NVM_TRANS_SHIFT) | mod;
  +
eeprom->len = length;
  +
memset(&ifr, 0, sizeof(ifr));
  +
strcpy(ifr.ifr_name, ethDev);
  +
  +
/*
  +
Get offset to EMP SR
  +
offset 0x48
  +
length 0x2
  +
*/
  +
eeprom->offset = 0x48 << 1;
  +
  +
ifr.ifr_data = (void*)eeprom;
  +
if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) die("ioctl");
  +
  +
uint16_t emp_offset = *(uint16_t*)(eeprom+1);
  +
printf("EMP SR offset: 0x%04x\n", emp_offset);
  +
  +
/*
  +
Get offset to PHY Capabilities 0
  +
emp_offset + 0x19
  +
length 0x2
  +
*/
  +
uint16_t cap_offset = 0x19;
  +
  +
eeprom->offset = (emp_offset + cap_offset) << 1;
  +
  +
ifr.ifr_data = (void*)eeprom;
  +
if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) die("ioctl");
  +
  +
uint16_t phy_offset = *(uint16_t*)(eeprom+1) + emp_offset + cap_offset;
  +
printf("PHY offset: 0x%04x\n", phy_offset);
  +
  +
/*
  +
Get PHY data size
  +
offset phy_offset
  +
*/
  +
eeprom->offset = phy_offset << 1;
  +
  +
ifr.ifr_data = (void*)eeprom;
  +
if( ioctl( fd, SIOCETHTOOL, &ifr ) == -1 ) die( "ioctl" );
  +
  +
uint16_t phy_cap_size = *(uint16_t*)(eeprom + 1);
  +
printf("PHY data struct size: 0x%04x\n", phy_cap_size);
  +
  +
/*
  +
Get misc0
  +
*/
  +
  +
uint16_t misc_offset = 0x8;
  +
  +
int i;
  +
uint16_t misc0 = 0x0;
  +
int change_count = 0;
  +
  +
for( i = 0; i < 4; ++i)
  +
{
  +
eeprom->offset = (phy_offset + misc_offset + (phy_cap_size + 1) * i) << 1;
  +
  +
ifr.ifr_data = (void*)eeprom;
  +
if( ioctl( fd, SIOCETHTOOL, &ifr ) == -1 ) die( "ioctl" );
  +
  +
uint16_t misc = *(uint16_t*)(eeprom + 1);
  +
printf( "MISC: 0x%04x", misc);
  +
  +
if( misc & 0x0800 ) printf( " <- locked\n" );
  +
else printf( " <- unlocked\n" );
  +
  +
if( misc != misc0 )
  +
{
  +
++change_count;
  +
misc0 = misc;
  +
}
  +
}
  +
  +
if( change_count > 1 ) die( "Different MISC's values" );
  +
  +
/*
  +
Patching
  +
*/
  +
  +
printf( "Ready to fix it? [y/N]: " );
  +
char choice = getchar();
  +
switch( choice )
  +
{
  +
case 'y':
  +
case 'Y':
  +
patching = 1;
  +
break;
  +
default:
  +
patching = 0;
  +
}
  +
  +
if( patching )
  +
{
  +
for( i = 0; i < 4; ++i)
  +
{
  +
eeprom->cmd = ETHTOOL_SEEPROM;
  +
eeprom->offset = (phy_offset + misc_offset + (phy_cap_size + 1) * i) << 1;
  +
  +
*(uint16_t*)(eeprom + 1) = misc0 ^ 0x0800;
  +
ifr.ifr_data = (void*)eeprom;
  +
if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) die("write");
  +
  +
sleep(1);
  +
}
  +
  +
// update checksum
  +
eeprom->cmd = ETHTOOL_SEEPROM;
  +
eeprom->magic = (devid << 16) | ((I40E_NVM_CSUM|I40E_NVM_SA) << I40E_NVM_TRANS_SHIFT) | mod;
  +
eeprom->len = 2;
  +
eeprom->offset = 0;
  +
  +
memset(&ifr, 0, sizeof(ifr));
  +
strcpy(ifr.ifr_name, ethDev);
  +
ifr.ifr_data = (void*)eeprom;
  +
if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) die("checksum");
  +
}
  +
  +
return 0;
  +
}
 
</PRE>
 
</PRE>
 
}}
 
}}
 
   
 
==<code>4</code>==
 
==<code>4</code>==

Версия 12:16, 25 февраля 2024


Ошибка ixgbe failed to load because an unsupported SFP+ module type was detected

x520

  • файл /etc/default/grub.d/60_custom.cfg
GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX ixgbe.allow_unsupported_sfp=1"

Или если более чем одна карта - ixgbe.allow_unsupported_sfp=1,1,1,1

  • Запустить update-grub
  • Файл /etc/modprobe.d/ixgbe.conf
options ixgbe allow_unsupported_sfp=1,1,1,1

Тут нужно указать список если более чем одна карта (или порт?)

x520 Unlocker

В теории это нужно что бы установить карту там, где драйвер не имеет опции отключения проверки.
Последний бит должен быть установлен 1 (в примере уже установлен, в обоих случаях )

ethtool -e enp3s0f1  offset 0x58 length 1
Offset		Values
------		------
0x0058:		fd
ethtool -e enp7s0f0 offset 0x58 length 1
Offset		Values
------		------
0x0058:		ff

Все манипуляции проводить только с 1 битом, например если было значение fe
( Бинарное 11111110 ) то записать следует ff( Бинарное 11111111

 ethtool -E enp1s0 magic 0x10fb8086 offset 0x58 value 0xff​

Магическое значение можно посмотреть так:

lspci -nn | grep 82599
03:00.0 Ethernet controller [0200]: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10fb] (rev 01)
03:00.1 Ethernet controller [0200]: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10fb] (rev 01)

[8086:10fb] --> 0x 10fb 8086

Что бы не возиться руками все те же манипуляции можно сделать скриптом

xl710

# ./xl710_unlock -n enp4s0f0
EMP SR offset: 0x67a8
PHY offset: 0x68f6
PHY data struct size: 0x000c
MISC: 0x6b0c <- locked
MISC: 0x6b0c <- locked
MISC: 0x6b0c <- locked
MISC: 0x6b0c <- locked
Ready to fix it? [y/N]: y


Makefile

syscalls.h

xl710_unlock.c

4