標準:MAC/PHY分層與鏈路排查)
簡介IEEE 802.3-2022 以太網(wǎng)標準正式版全文面向網(wǎng)絡設備研發(fā)工程師、協(xié)議棧開發(fā)者、測試認證人員及高校網(wǎng)絡方向師生用于查閱從 1Mb/s 到 400Gb/s 各速率的 MAC、MII、PHY 與 CSMA/CD 規(guī)范支持產(chǎn)品設計選型、協(xié)議實現(xiàn)對照與標準符合性驗證。資源包內為1個PDF文件共7025頁體量約93.79MB相比2018版新增1400余頁主要補充25G至100G相關條款并修訂10G內容同時整合此前各項修訂需注意802.3df-2024、802.3ck-2022、802.3db-2022等后續(xù)修訂未納入涉及400/800Gb/s新進展時需另行查閱。文檔按總則、MAC、各速率PHY、管理信息庫與術語索引分層組織便于按章節(jié)定位。已有287人學習下載適合作為案頭標準手冊長期備查。1. 7000 頁不是冗余以太網(wǎng)標準真正的野心是讓 1 Mb/s 和 400 Gb/s 共用一套 MAC翻開這份 802.3-2022 行業(yè)標準 IEEE802.3 文檔第一反應通常是7025 頁是不是注水了反直覺的地方在于頁數(shù)暴漲的那 1400 多頁幾乎全砸在 25G 到 100G 的 PMD、FEC 和接口細節(jié)上而管幀格式的那幾頁和上世紀八十年代幾乎一模一樣。同一套 MAC 既要伺候 1 Mb/s 的同軸電纜也要伺候 400 Gb/s 的背板靠的不是把舊東西刪掉重寫而是在中間插了一層又一層適配殼。搞懂這層殼怎么長出來的你才知道為什么換個光模塊不用改驅動、為什么 100G 鏈路起不來時第一步該看協(xié)商而不是看光功率。2. 分層與解耦為什么換了物理層MAC 一行都不用改MAC 這一層做的事情少得可憐組幀、填源和目的地址、算 32 位 CRC、按規(guī)則決定什么時候能發(fā)。它完全不知道對端是 10BASE-T 的雙絞線還是 400GBASE-DR4 的并行光。真正讓這個謊言成立的是夾在 MAC 和物理介質之間的一串子層——調和子層RS、介質無關接口MII、物理編碼子層PCS、物理介質接入子層PMA、物理介質相關子層PMD。標準把這串東西寫成一條流水線每一層只跟上下相鄰的層打交道速率和介質的所有臟活都被關在 PCS 以下。2.1 RS 與 MII把 PHY 差異擋在 MAC 之外的薄殼RS 的職責聽上去微不足道把 MAC 送來的串行位流按 MII 的位寬切開發(fā)送時把前導碼和 SFD 交出去接收時把載波偵聽和沖突檢測的信號翻譯成 MAC 認識的 PLS 原語。但正是這層“翻譯”把 MAC 和 PHY 徹底解耦了。MAC 可以做成一份 RTL 或者一個軟核在 FPGA 里跑十年不動PHY 從 100BASE-TX 換到 1000BASE-X 再到 25GBASE-R換的是 MII 之上的握手方式和 MII 本身的形態(tài)MAC 側看到的仍然是“有載波 / 無載波 / 收到一個字節(jié)”。常見實現(xiàn)里MII 并不一定有對應的引腳。芯片內部模塊之間直接按 MII 的時序約定傳信號甚至只在邏輯上遵守位寬和時鐘關系只有跨芯片、跨板卡時才落到真實的并行總線上。理解這一點讀標準時就不會糾結某個接口為什么既描述了引腳又描述了幀結構——它們描述的其實是同一個邏輯契約的兩種落地形態(tài)。2.2 MII 家族的退化史并行位寬撞墻之后轉向串行這條演進線索值得單獨拎出來因為它解釋了大量“為什么這個接口長這樣”的疑問。早期的 MII 用 4 位并行、25 MHz 時鐘湊出 100 Mb/s千兆的 GMII 把位寬加到 8 位、時鐘提到 125 MHz萬兆的 XGMII 直接把位寬拉到 32 位并改用雙沿采樣。位寬越加越寬時鐘越來越高板級時序收斂越來越難于是方向掉頭SGMII 之類改成串行把時鐘嵌進數(shù)據(jù)里用 8B/10B 編碼保證足夠的跳變讓接收端恢復時鐘。這個權衡可以用一行算式看清楚。def mii_clock(rate_gbps: float, width_bits: int, ddr: bool False) - float: rate_gbps: 單向線速率單位 Gb/s width_bits: 每個方向的并行位寬 ddr: 是否雙沿采樣上下沿都傳數(shù)據(jù) 返回該接口需要的時鐘頻率單位 MHz edges_per_cycle 2 if ddr else 1 return rate_gbps * 1000 / (width_bits * edges_per_cycle) for name, rate, width, ddr in [ (MII, 0.1, 4, False), # 25 MHz板級輕松 (GMII, 1.0, 8, False), # 125 MHz開始要關注走線 (XGMII, 10.0, 32, True), # 156.25 MHz32 位并行走線已經(jīng)很難 (CGMII, 100.0, 64, True), # 781.25 MHz單總線已不現(xiàn)實 ]: print(f{name:6s} {mii_clock(rate, width, ddr):8.2f} MHz)跑出來的 781.25 MHz 是個信號到了 100G靠加寬總線換低時鐘這條路走到頭了。所以 40G/100G 之后的 MII 在實現(xiàn)上被切成多條 lane每條 lane 跑一個可以接受的速率再在 PCS 里做 lane 分發(fā)和對齊。這也解釋了標準里為什么反復出現(xiàn)“PCS lane marker”“l(fā)ane 對齊”這類詞——它們不是可選的優(yōu)化而是并行接口撐不住之后的必然產(chǎn)物。提示讀某條 clause 里的位寬和時鐘時先算一遍這個式子。算出來超過 200 MHz 的并行總線基本可以斷定標準里會有配套的多 lane 方案。2.3 幀格式里那個“一個字段兩種含義”的歷史包袱以太網(wǎng)幀第 13、14 字節(jié)是一個被復用過的字段小于等于 15000x05DC時它表示后面 LLC 數(shù)據(jù)的長度大于等于 15360x0600時它表示上層協(xié)議類型。1501 到 1535 這 35 個值在標準里是未定義的縫隙。這個設計是歷史妥協(xié)的化石——早期以太網(wǎng)需要一個長度字段讓接收端知道有效載荷到哪結束后來上層協(xié)議需要一個類型字段來做多路分解標準干脆讓同一個位置承擔兩種語義用數(shù)值范圍區(qū)分。寫解析代碼時這個坑非常具體。def decode_ethernet_frame(raw: bytes) - dict: raw: 從目的 MAC 首字節(jié)開始、到 FCS 之前結束的字節(jié)串。 7 字節(jié)前導碼 0xAA 和 1 字節(jié) SFD 0xAB 已被 PHY/RS 剝掉。 if len(raw) 14: raise ValueError(不足 14 字節(jié)連 DA SA Type/Length 都不夠) dst :.join(f{b:02x} for b in raw[0:6]) src :.join(f{b:02x} for b in raw[6:12]) tlv int.from_bytes(raw[12:14], big) if tlv 0x0600: # 1536 起按 EtherType 解釋 mode, body ethertype, raw[14:] elif tlv 1500: # 1500 及以下按長度解釋 mode, body length, raw[14:14 tlv] else: # 1501~1535 是標準里留的縫隙 raise ValueError(f0x{tlv:04x} 落在未定義區(qū)間幀大概率被截斷) # 最小幀 64 字節(jié)含 4 字節(jié) FCS不足的由發(fā)送端補零接收端要靠長度判斷 padded len(raw) 4 64 return {dst: dst, src: src, tlv: tlv, mode: mode, payload_len: len(body), padded: padded}幾個參數(shù)要拎清楚。raw不包含 FCS因為 CRC 一般在 MAC 里校驗完就丟了padded判斷的是補零46 字節(jié)的最小載荷是為了讓幀從目的地址到 FCS 湊滿 64 字節(jié)這個數(shù)字直接來自下一章的沖突檢測時間預算不是隨便定的長度模式下body只取到長度字段聲明的字節(jié)數(shù)后面的補零必須丟掉否則上層會讀到垃圾。2.4 MDI 上的另一件事PoE 的檢測與分級介質相關接口MDI是以太網(wǎng)和電纜的物理分界供電也發(fā)生在這里。標準把直流電壓疊加在雙絞線的中心抽頭上數(shù)據(jù)變壓器對直流是隔離的所以供電和數(shù)據(jù)互不干擾。關鍵在于上電之前的那幾步PSE 先輸出一個 2.8 V 到 10 V 之間的探測電壓測簽名電阻標稱 25 kΩ 左右確認是對端設備之后才做分級用電流或電壓簽名區(qū)分功率檔位最后才把完整電壓加上去。為什么探測電壓壓得這么低因為任何合規(guī) PHY 的輸入端都能扛住 10 V而一個不帶 PoE 功能的普通網(wǎng)卡大概率沒有那個 25 kΩ 簽名于是 PSE 就停在探測階段不動。這是用極小的代價換來了“插錯口不燒設備”的安全性。類型PSE 輸出上限PD 端可用功率典型分級方式Type 115.4 W12.95 W單事件Class 0~3Type 230 W25.5 W單事件 兩級探測Class 4Type 360 W51 W雙事件分級Class 5~6Type 490 W71.3 W雙事件分級 AutoclassClass 7~8表里 PSE 輸出和 PD 可用之間那一截損耗是通道損耗標準允許它就是這么大。單對線的場景另有 PoDL 的一套分級原理相同但電壓等級和類別數(shù)不同別把兩套參數(shù)混著用。3. 從沖突檢測到全雙工CSMA/CD 的時間預算為什么是 512 bit半雙工共享介質上發(fā)送方必須在沖突信號傳回來之前一直占著線否則它會以為發(fā)送成功沖突雙方的數(shù)據(jù)全廢。這條約束翻譯成公式很短最小幀的發(fā)送時間必須大于等于信號往返一圈的時間。10 Mb/s 時標準取了 512 bit 時間也就是 51.2 微秒配上同軸電纜的傳播速度和最多四個中繼器就得到了那個著名的 2500 米網(wǎng)絡直徑。512 這個數(shù)字不是設計出來的是被光速和當時的器件延遲逼出來的。3.1 slot time 與網(wǎng)絡直徑一個用光速算出來的數(shù)字把這條約束寫成一個可驗證的預算鏈路能不能在半雙工下工作就一目了然。def slot_time_us(speed_mbps: float, slot_bits: int 512) - float: 512 bit 時間在不同速率下折算成微秒這就是往返預算的總盤子 return slot_bits / speed_mbps def topology_delay_us(cable_len_m: float, repeaters: int, prop_us_per_km: float 5.0, phy_delay_us: float 0.5, repeater_delay_us: float 0.5) - float: 估一條拓撲占用多少往返時間電纜按往返算其余按單程延遲乘 2 或按個數(shù)算 cable 2 * (cable_len_m / 1000.0) * prop_us_per_km fixed 2 * phy_delay_us repeaters * repeater_delay_us return cable fixed for speed, length, reps in [(10, 2500, 4), (100, 200, 2), (1000, 100, 0)]: budget slot_time_us(speed) used topology_delay_us(length, reps) flag 夠用 if used budget else 超預算 print(f{speed:5d} Mb/s {length:5d} m {reps} 中繼器 f預算 {budget:6.2f} μs 占用 {used:5.2f} μs {flag})10 Mb/s 和 100 Mb/s 兩行都還能過到 1000 Mb/s 半雙工預算只剩 0.512 微秒比一個 PHY 自身的延遲還小物理上不可能滿足。標準的解法是載波擴展把短幀在物理層補齊到 512 字節(jié)再發(fā)讓占用介質的時間重新拉長到預算之內再疊加幀突發(fā)把補齊的開銷攤薄。這條補丁只在千兆半雙工上存在過屬于典型的“為了兼容舊機制而付出的額外復雜度”。參數(shù)上要留意prop_us_per_km取 5 是工程近似實際電纜里電磁波速度大約是光速的 0.6 到 0.77 倍折算下來每公里 4 到 5.5 微秒。phy_delay_us和repeater_delay_us才是真正吃掉預算的大頭這也是為什么速率每提一檔網(wǎng)絡直徑就斷崖式下跌——不是電纜變差了是固定延遲在越來越小的預算里占比越來越大。3.2 全雙工之后沖突消失但 Pause 幀和 buffer 頂了上來全雙工點對點鏈路里收發(fā)各走一對線沖突在物理上不存在CSMA/CD 的整套機制被整體旁路最小幀長的約束也從“必須”退化成“保持格式兼容”。沖突這個矛盾消失之后新的矛盾立刻補位發(fā)送方比接收方快接收端的緩沖填滿就丟幀。標準給的答案是 MAC 控制幀也就是 Pause 幀。它用類型字段 0x8808 標記操作碼 0x0001目的地址固定為 01-80-C2-00-00-01這個地址被規(guī)定為“不轉發(fā)”所以暫停請求只影響相鄰一跳。幀里帶的參數(shù)以 512 bit 時間為單位表示“請對方暫停多久”。設計上它是一條建議而不是命令接收方可以完全忽略也可以提前恢復發(fā)送。這個軟約束在存儲轉發(fā)設備上帶來的問題不小——上游停了下游的緩沖還在往外吐鏈路抖動會沿著路徑累積。真正踩過坑的人對這段歷史都有血淚經(jīng)驗后來在無損網(wǎng)絡里演化出的按優(yōu)先級流控一旦形成環(huán)路就會出現(xiàn)暫停幀互相鎖死整片網(wǎng)絡進入死鎖排查起來像黑匣子。這也從側面說明把流控做在 MAC 層、做成不帶拓撲感知的單跳信號本身就是個有局限的設計。3.3 PLCA把 CSMA/CD 的舊思路搬到單對線上做時分復用單對雙絞線的多點場景一條線掛多個節(jié)點沒有交換機重新把共享介質的問題帶了回來。10 Mb/s 的速率下往返預算又變得很緊CSMA/CD 的退避算法在長線纜上效率極低。標準給出的方案是物理層沖突避免在一個混合段里選一個協(xié)調者由它周期性發(fā)出 BEACON 開啟一輪各節(jié)點按節(jié)點 ID 順序依次拿到自己的發(fā)送機會輪到誰誰發(fā)沒輪到的閉嘴。這套機制的巧妙之處在于它把調度做在了 PHY 里而不是 MAC 里。MAC 看到的仍然是一個“可以發(fā)”的信號完全不用改。輪轉過程中還有一個提交階段用來讓新上線的節(jié)點在不打亂現(xiàn)有順序的前提下插進來。節(jié)點數(shù)被限制在很小的范圍混合段里最多 8 個因為節(jié)點越多一輪的時間越長每個節(jié)點分到的帶寬越少。4. 物理層編碼與協(xié)商64B/66B、RS-FEC 和 AN 是怎么決定鏈路能不能起來的一條鏈路起不來九成的情況下問題不在光功率而在兩端沒有對上同一套“語言”編碼方式、FEC 開關、lane 數(shù)量、甚至是否啟用節(jié)能特性。這些參數(shù)全都在物理層協(xié)商階段確定而協(xié)商本身又必須在鏈路還沒建立的時候完成于是標準被迫設計了一套比正常速率慢得多、但極其魯棒的通信方式。4.1 編碼譜系4B/5B、8B/10B、64B/66B 與那段被浪費的帶寬線路編碼要解決兩件事讓接收端能從數(shù)據(jù)里恢復時鐘足夠的電平跳變以及保持直流平衡不讓變壓器飽和。4B/5B 和 8B/10B 都用 25% 的額外帶寬換這兩件事在百兆和千兆時代這筆賬劃算。到了 100G25% 意味著白扔 25 Gb/s 的線路帶寬和相應的功耗賬算不過來了。64B/66B 的做法是把 64 位載荷加 2 位同步頭打成一塊開銷降到 3.125%。跳變密度不再靠編碼表保證而是靠后面的自同步擾碼器。同步頭的兩個比特只有 01純數(shù)據(jù)和 10含控制字符兩種合法取值00 和 11 從未出現(xiàn)——這個性質讓接收端可以在任意位置開一個 66 位的滑窗靠非法組合快速找到塊邊界。SYNC_LEGAL {0b01: data, 0b10: control} # 00 / 11 非法可直接判錯 def pack_block(block64: int) - int: 64 位載荷 2 位同步頭拼成 66 位一塊開銷 2/64 3.125% return (0b01 64) | (block64 ((1 64) - 1)) def unpack_block(block66: int): 返回 (載荷, 類型)同步頭非法時返回 (None, 錯誤說明) sync (block66 64) 0b11 if sync not in SYNC_LEGAL: return None, sync header 非法塊邊界大概率丟了 return block66 ((1 64) - 1), SYNC_LEGAL[sync]pack_block里那個掩碼不能省調用方傳進來的高位如果沒清干凈會污染同步頭接收端看到 11 就判定失鎖。unpack_block的返回值設計成二元組而不是拋異常是因為真實接收機在失鎖后需要連續(xù)統(tǒng)計非法同步頭的數(shù)量來決定是否重新對齊單次失敗不該中斷整個接收流程。4.2 FEC 與交織為什么 100G 之后糾錯成了必選項PAM4 調制一個符號攜帶 2 比特眼圖從 NRZ 的一個變成三個同樣的噪聲容限下信噪比要求陡增。速率的提升又把符號率推高信道損耗加劇。結果就是原始誤碼率惡化到 1e-4 到 1e-5 這個量級靠物理層的模擬均衡已經(jīng)壓不下去了必須引入前向糾錯。100G 及以上的以太網(wǎng)用里德-所羅門碼作用在 GF(2^10) 上一個符號 10 比特。兩套參數(shù)值得記住一套是 528 符號里 14 個校驗符號能糾 7 個符號錯開銷約 2.7%另一套是 544 符號里 30 個校驗符號能糾 15 個開銷約 5.8%。前者多用于電接口和背板后者多用于光接口因為光鏈路的信噪比更緊張。選哪套不是自由的PMD 條款里寫死了。代價有三塊。一是延遲編解碼本身加上交織深度在 cut-through 轉發(fā)設備上能明顯測出來二是功耗FEC 邏輯在 400G 端口上是個不小的發(fā)熱源三是線路速率必須提高因為要承載校驗符號實際波特率比標稱速率高幾個百分點。這三塊代價換來的是誤碼率從 1e-4 量級降到 1e-15 以下把“鏈路能通”變成了“鏈路能穩(wěn)定跑滿”。交織是配合 FEC 的另一個手段。突發(fā)錯誤會連續(xù)打壞一串符號超過糾錯能力就整塊報廢把編碼后的符號按固定規(guī)則打散到多條 lane 上突發(fā)錯誤就被攤成了分散的單符號錯落在糾錯能力之內。代價同樣是延遲交織越深延遲越大。4.3 Auto-Negotiation 與 link training兩端怎么談出共同語言協(xié)商要解決一個雞生蛋的問題要談速率得先能通信可通信本身依賴速率已經(jīng)談好。標準的解法是用一套獨立于業(yè)務速率的低速信令。百兆和千兆用的是快速鏈路脈沖一串 33 個脈沖其中 16 個承載鏈路碼字17 個提供時鐘信息用最笨的曼徹斯特式跳變讓對端即使頻率對不準也能解出來。鏈路碼字的基頁只有 16 位塞不下多少東西。低位是 5 位選擇符標識這是以太網(wǎng)中間一串是技術能力位對端據(jù)此判斷雙方支持的交集最高位是“還有下一頁”標志次高位是確認再次是遠程故障。能力不夠就把后續(xù)的下一頁翻出來一頁一頁把 FEC、節(jié)能、通道參數(shù)這些擴展能力傳過去。字段語義位序簡化作用選擇符標識使用的協(xié)議族以太網(wǎng)是固定編碼技術能力位聲明支持的速率與雙工組合雙方取交集遠程故障告訴對端“我這邊收不到有效信號”確認握手應答保證雙方都讀到了對方的頁下一頁標志能力太多時翻頁承載擴展參數(shù)背板和 10G 以上的銅纜場景用的是另一套基于差分曼徹斯特編碼的協(xié)商頁更長能塞進 FEC 意愿、lane 數(shù)量、通道損耗這些信息。協(xié)商完成之后還有一步 link training兩端用已知的訓練序列反復調整發(fā)送端的均衡系數(shù)把眼圖調到最優(yōu)然后才切換到正常數(shù)據(jù)。這個過程對使用者是不可見的但它是高速背板鏈路能起來的前提。節(jié)能特性搭的是同一班車支持低功耗閑置的一端在下一頁里聲明能力雙方都支持才啟用。這也是排查時容易忽略的地方——鏈路在某些對端上起不來原因可能是協(xié)商里某個可選能力位對不上而不是物理層壞了。5. 常見問題與排查讀這份 7025 頁文檔最容易翻車的五個地方這份文檔的體量和結構決定了它不好用。它不是一本從頭讀到尾的書而是一份按條款號索引的契約集合加上幾十個可選特性矩陣。翻車通常不是因為技術難而是因為找錯了地方或者用錯了版本假設。5.1 現(xiàn)象查不到 800G 的條款現(xiàn)象很直接按目錄翻遍全篇找不到 800 Gb/s 相關的內容懷疑文檔缺頁或者下載不完整。原因是版本邊界。這份 2022 版是 2018 版的整體修訂本文還有配套的精品資源點擊獲取