4. 解析SFF-8472速率标识

任务说明

本案例实现一个SFF-8472速率标识解析器,输入为A0h地址0x00-0x7D处的标识字节(Byte 0-1为速率标识),输出为人类可读的速率能力列表。解析器需覆盖SFF-8472规范中定义的10种速率标识位,并正确处理保留位。

速率标识位定义

SFF-8472中速率标识位于A0h地址偏移0x00(Byte 0)和0x01(Byte 1),各bit含义如下:

  • Byte 0 (0x00):Bit7-4保留;Bit3=1G Ethernet;Bit2=2G Fibre Channel;Bit1=4G Fibre Channel;Bit0=10G Ethernet
  • Byte 1 (0x01):Bit7=10G Fibre Channel;Bit6=40G Ethernet;Bit5=40G Fibre Channel(若支持);Bit4=100G Ethernet;Bit3-0保留

代码实现


#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define RATE_BYTE0_ADDR 0x00
#define RATE_BYTE1_ADDR 0x01

typedef struct {
    uint8_t byte0;
    uint8_t byte1;
} rate_id_t;

const char* rate_desc[] = {
    "10G Ethernet",      // byte0 bit0
    "4G Fibre Channel",  // byte0 bit1
    "2G Fibre Channel",  // byte0 bit2
    "1G Ethernet",       // byte0 bit3
    "100G Ethernet",     // byte1 bit4
    "40G Fibre Channel", // byte1 bit5
    "40G Ethernet",      // byte1 bit6
    "10G Fibre Channel"  // byte1 bit7
};

void parse_rate_identifier(uint8_t byte0, uint8_t byte1) {
    printf("速率标识寄存器值: Byte0=0x%02X, Byte1=0x%02X\n", byte0, byte1);
    printf("支持的速率:\n");
    
    int found = 0;
    // 检查Byte0 (bit0-bit3)
    for (int i = 0; i < 4; i++) {
        if (byte0 & (1 << i)) {
            printf("  - %s\n", rate_desc[i]);
            found = 1;
        }
    }
    // 检查Byte1 (bit4-bit7)
    for (int i = 4; i < 8; i++) {
        if (byte1 & (1 << (i - 4))) {
            printf("  - %s\n", rate_desc[i]);
            found = 1;
        }
    }
    
    if (!found) {
        printf("  (无已声明速率)\n");
    }
    
    // 检查保留位
    if (byte0 & 0xF0) {
        printf("警告: Byte0保留位非零 (0x%02X)\n", byte0 & 0xF0);
    }
    if (byte1 & 0x0F) {
        printf("警告: Byte1保留位非零 (0x%02X)\n", byte1 & 0x0F);
    }
}

int main() {
    // 示例1: 常见10G SFP+模块 (10G Ethernet + 10G Fibre Channel)
    printf("=== 示例1: 10G SFP+ SR模块 ===\n");
    parse_rate_identifier(0x01, 0x80);
    
    printf("\n=== 示例2: 40G QSFP+模块 ===\n");
    // 40G Ethernet + 40G Fibre Channel
    parse_rate_identifier(0x00, 0x60);
    
    printf("\n=== 示例3: 双速率模块 ===\n");
    // 1G Ethernet + 10G Ethernet
    parse_rate_identifier(0x09, 0x00);
    
    printf("\n=== 示例4: 非法保留位测试 ===\n");
    parse_rate_identifier(0xF1, 0x8F);
    
    return 0;
}

编译与运行


gcc -o rate_parser rate_parser.c
./rate_parser

验证方法

运行程序后,观察输出是否满足以下判定标准:

  1. 示例1输出应包含“10G Ethernet”和“10G Fibre Channel”,且无警告;
  2. 示例2输出应包含“40G Ethernet”和“40G Fibre Channel”;
  3. 示例3输出应包含“1G Ethernet”和“10G Ethernet”;
  4. 示例4应输出“10G Ethernet”和“10G Fibre Channel”,同时显示两条保留位警告(Byte0高位0xF0、Byte1低位0x0F);
  5. 所有bit位与速率名称的映射关系与SFF-8472规范一致。
Byte 0 (A0h + 0x00) Bit7-4 (保留) Bit3: 1G Ethernet Bit2: 2G FC Bit1: 4G FC Bit0: 10G Ethernet 示例: 0x01 → Bit0 Byte 1 (A0h + 0x01) Bit7: 10G FC Bit6: 40G Ethernet Bit5: 40G FC Bit4: 100G Ethernet Bit3-0 (保留) 示例: 0x80 → Bit7 = 10G FC 解析流程 读取Byte0/Byte1 逐bit检查置位 映射速率名称 输出结果

预期输出


=== 示例1: 10G SFP+ SR模块 ===
速率标识寄存器值: Byte0=0x01, Byte1=0x80
支持的速率:
  - 10G Ethernet
  - 10G Fibre Channel

=== 示例2: 40G QSFP+模块 ===
速率标识寄存器值: Byte0=0x00, Byte1=0x60
支持的速率:
  - 40G Fibre Channel
  - 40G Ethernet

=== 示例3: 双速率模块 ===
速率标识寄存器值: Byte0=0x09, Byte1=0x00
支持的速率:
  - 10G Ethernet
  - 1G Ethernet

=== 示例4: 非法保留位测试 ===
速率标识寄存器值: Byte0=0xF1, Byte1=0x8F
支持的速率:
  - 10G Ethernet
  - 10G Fibre Channel
警告: Byte0保留位非零 (0xF0)
警告: Byte1保留位非零 (0x0F)

该解析器可直接嵌入I2C读取固件中,将读取到的A0h地址0x00-0x01字节传入parse_rate_identifier()即可完成速率能力解析。实际应用中需注意Byte1的Bit5(40G Fibre Channel)仅在模块支持该速率时才有定义,部分早期模块此位可能为0。