01 · QUESTION
무엇을 증명할 것인가
interface가 DOWN인 이유가 cable/PHY link 문제인지, PHY-MAC interface timing 문제인지, Linux state machine 문제인지 어떻게 분리하는가?
RJ45/magnetics와 MDI electrical 상태에서 PHY reset, MDIO register, auto-negotiation, RGMII/SGMII timing과 Linux phylib/phylink까지 올라갑니다. 이 글은 Linux 로그를 출발점으로 삼지 않습니다. 같은 사건이 보드, controller, firmware, kernel에서 어떤 이름과 번호로 바뀌는지 아래에서 위로 연결합니다.
02 · CONTRACT
입력과 완료 조건
| 구분 | 확인할 내용 |
|---|---|
| 입력 | PHY 전원과 reference clock, reset, magnetics/connector, MAC-PHY interface와 MDIO bus |
| 출력 | speed/duplex/pause가 합의되고 MAC clock와 datapath가 같은 mode로 설정된 carrier-on net_device |
| 소유권 | PHY는 line link와 negotiation, MAC은 frame/DMA, phylib/phylink는 두 hardware state의 Linux 동기화를 소유 |
| 완료 조건 | `ethtool` link detected와 실제 frame RX/TX counter가 모두 증가하고 error counter가 안정적 |
03 · BOTTOM-UP
완전히 아래에서 시작하는 8단계
PHY analog/digital/I/O rail의 전압과 ramp 순서, crystal/clock, reset pulse를 확인한다. PHY address, interface mode, master/slave 같은 strap pin은 reset 해제 시 sampling된다. magnetics center tap과 termination, RJ45 pair mapping이 틀리면 MDIO는 살아 있어도 cable link가 생기지 않는다.
증거: 전원/clock/reset scope, strap level, schematic와 PHY datasheet pin state
10/100/1000BASE-T는 속도별 signaling과 pair 사용이 다르다. Auto MDI-X, cable diagnostics와 pair swap 기능도 PHY capability에 의존한다. 링크가 특정 cable 길이 또는 온도에서만 실패하면 Linux보다 return loss, clock jitter, magnetics와 PCB pair 품질을 먼저 본다.
증거: PHY cable diagnostic, pair status, link pulse/eye measurement, symbol error counter
MDC/MDIO는 management bus이며 packet data path가 아니다. Clause 22는 5-bit PHY/reg address, Clause 45는 MMD device와 16-bit register address를 사용한다. pull-up, turnaround bit와 MDC frequency가 맞지 않으면 PHY ID가 0xffff/0x0000으로 보인다.
증거: logic analyzer MDIO frame, BMCR/BMSR, PHYID1/2, MMD access 결과
양쪽이 advertisement를 교환해 공통 speed/duplex와 pause capability를 결정한다. 강제 speed와 autoneg 상대를 섞으면 parallel detection 때문에 duplex mismatch가 생길 수 있다. 1000BASE-T master/slave resolution과 EEE advertisement도 별도 상태다.
증거: local/LP advertisement, AN complete, master/slave status, pause resolution
parallel interface는 data/clock edge와 trace delay가 중요하다. RGMII는 약 2ns internal/PCB delay 책임을 MAC, PHY, board 중 정확히 한 곳이 져야 한다. SGMII는 serial PCS auto-negotiation과 line rate가 copper PHY의 MDI negotiation과 별도일 수 있다.
증거: interface clock, internal delay strap/register, PCS status, RX CRC/alignment error
Device Tree의 `phy-mode`, `phy-handle`, reset GPIO, delays, managed/fixed-link가 hardware 연결을 표현한다. `rgmii-id`, `rgmii-rxid`, `rgmii-txid`는 delay 책임을 명시한다. 잘못된 값은 probe 성공 뒤에 packet corruption으로 나타날 수 있다.
증거: live DT와 schematic, PHY strap/register, MAC driver parsed mode
MDIO bus가 PHY를 발견하고 driver가 PHY ID로 bind된다. phylib가 autoneg, link polling/interrupt와 state transition을 관리하며 phylink는 MAC validate/config/link_up callback을 조정한다. carrier는 PHY link 결과와 MAC 설정 완료 뒤에 올려야 한다.
증거: PHY driver bind, phylib state, phylink resolve log, netif_carrier state
`ethtool`의 advertised/supported/link partner 결과와 driver/PHY statistics를 먼저 저장한다. ping보다 먼저 MAC RX good frame, CRC, alignment, missed frame과 PHY symbol error를 본다. packet이 MAC에 도착한 뒤의 문제는 DMA/NAPI 글로 넘긴다.
증거: `ethtool`, `ethtool -S`, `ip -s link`, PHY statistics와 packet capture
0. Board · PHY rail, reset, strap과 magnetics
PHY analog/digital/I/O rail의 전압과 ramp 순서, crystal/clock, reset pulse를 확인한다. PHY address, interface mode, master/slave 같은 strap pin은 reset 해제 시 sampling된다. magnetics center tap과 termination, RJ45 pair mapping이 틀리면 MDIO는 살아 있어도 cable link가 생기지 않는다.
남길 증거: 전원/clock/reset scope, strap level, schematic와 PHY datasheet pin state
MDIO ID가 읽힌다는 사실은 MDI analog path가 정상이라는 증거가 아니다.
1. MDI · link pulse, pair detect와 line coding
10/100/1000BASE-T는 속도별 signaling과 pair 사용이 다르다. Auto MDI-X, cable diagnostics와 pair swap 기능도 PHY capability에 의존한다. 링크가 특정 cable 길이 또는 온도에서만 실패하면 Linux보다 return loss, clock jitter, magnetics와 PCB pair 품질을 먼저 본다.
남길 증거: PHY cable diagnostic, pair status, link pulse/eye measurement, symbol error counter
PHY가 signal detect를 못 하면 auto-negotiation state machine도 시작되지 않는다.
2. MDIO · Clause 22/45 register 접근
MDC/MDIO는 management bus이며 packet data path가 아니다. Clause 22는 5-bit PHY/reg address, Clause 45는 MMD device와 16-bit register address를 사용한다. pull-up, turnaround bit와 MDC frequency가 맞지 않으면 PHY ID가 0xffff/0x0000으로 보인다.
남길 증거: logic analyzer MDIO frame, BMCR/BMSR, PHYID1/2, MMD access 결과
BMSR link bit는 latch-low 특성이 있을 수 있어 두 번 읽는 규칙을 확인한다.
3. AN · Advertisement, partner ability와 resolved mode
양쪽이 advertisement를 교환해 공통 speed/duplex와 pause capability를 결정한다. 강제 speed와 autoneg 상대를 섞으면 parallel detection 때문에 duplex mismatch가 생길 수 있다. 1000BASE-T master/slave resolution과 EEE advertisement도 별도 상태다.
남길 증거: local/LP advertisement, AN complete, master/slave status, pause resolution
link bit 하나가 아니라 resolved speed, duplex, pause와 fault bit를 함께 본다.
4. PHY-MAC · MII/RMII/RGMII/SGMII/USXGMII
parallel interface는 data/clock edge와 trace delay가 중요하다. RGMII는 약 2ns internal/PCB delay 책임을 MAC, PHY, board 중 정확히 한 곳이 져야 한다. SGMII는 serial PCS auto-negotiation과 line rate가 copper PHY의 MDI negotiation과 별도일 수 있다.
남길 증거: interface clock, internal delay strap/register, PCS status, RX CRC/alignment error
carrier는 올라오는데 모든 frame이 CRC error면 RGMII timing과 MAC mode를 먼저 의심한다.
5. DT/ACPI · phy-mode, phy-handle와 fixed-link
Device Tree의 `phy-mode`, `phy-handle`, reset GPIO, delays, managed/fixed-link가 hardware 연결을 표현한다. `rgmii-id`, `rgmii-rxid`, `rgmii-txid`는 delay 책임을 명시한다. 잘못된 값은 probe 성공 뒤에 packet corruption으로 나타날 수 있다.
남길 증거: live DT와 schematic, PHY strap/register, MAC driver parsed mode
DT 문자열을 그대로 믿지 말고 실제 clock edge와 delay 설정을 대조한다.
6. phylib · PHY state machine과 adjust link
MDIO bus가 PHY를 발견하고 driver가 PHY ID로 bind된다. phylib가 autoneg, link polling/interrupt와 state transition을 관리하며 phylink는 MAC validate/config/link_up callback을 조정한다. carrier는 PHY link 결과와 MAC 설정 완료 뒤에 올려야 한다.
남길 증거: PHY driver bind, phylib state, phylink resolve log, netif_carrier state
PHY interrupt와 polling mode가 섞이지 않았는지, link-change event가 MAC callback까지 도달하는지 확인한다.
7. Linux · ethtool에서 실제 frame까지
`ethtool`의 advertised/supported/link partner 결과와 driver/PHY statistics를 먼저 저장한다. ping보다 먼저 MAC RX good frame, CRC, alignment, missed frame과 PHY symbol error를 본다. packet이 MAC에 도착한 뒤의 문제는 DMA/NAPI 글로 넘긴다.
남길 증거: `ethtool`, `ethtool -S`, `ip -s link`, PHY statistics와 packet capture
link, MAC frame counter, DMA descriptor와 socket 수신을 각기 다른 checkpoint로 둔다.
04 · DIAGRAMS
주소와 상태가 이동하는 모습
PHY 전원과 reference clock, reset, magnetics/connector, MAC-PHY interface와 MDIO bus
PHY는 line link와 negotiation, MAC은 frame/DMA, phylib/phylink는 두 hardware state의 Linux 동기화를 소유
speed/duplex/pause가 합의되고 MAC clock와 datapath가 같은 mode로 설정된 carrier-on net_device
`ethtool` link detected와 실제 frame RX/TX counter가 모두 증가하고 error counter가 안정적
05 · DETAILED MANUAL
PHY, MDIO, PCS와 MAC 경계를 분해하는 상세 매뉴얼
링크 LED나 `ethtool` 한 줄만으로 PHY 경계를 통과했다고 판정하지 않습니다. 전원과 strap부터 Clause 22/45 관리 프레임, auto-negotiation 결과, RGMII clock-data skew, SGMII/PCS in-band status, phylib/phylink callback까지 동일한 link 사건을 이어서 확인합니다.
공개적으로 다시 확인할 수 있는 자료
공개되지 않은 vendor register나 integration별 offset을 추측해서 채우지 않았습니다. 아래 제조사 자료, architecture 문서와 Linux v6.18.37 원본에서 다시 확인할 수 있는 범위만 사용했습니다.
Linux PHY Abstraction Layer
PHY 장치, MDIO, link 상태와 PHY driver의 공개 Linux 계약
Linux phylink
PHY, fixed-link, in-band PCS와 MAC callback의 관계
Linux Ethernet controller binding
phy-mode, phy-handle, fixed-link와 managed 속성
Linux v6.18.37 phy_device.c
PHY 장치 생성, attach, start/stop과 상태 갱신
Linux v6.18.37 phylink.c
link resolve, MAC config, link up/down 실행 경로
TI DP83867IR/CR datasheet
strap, RGMII/SGMII, extended register, clock, interrupt와 진단 기능
TI DP83867 RGMII timing budget
0.25ns 단계 internal delay와 setup/hold margin 계산 및 측정 절차
Linux DP83867 driver
DT 속성, RGMIIDCTL, FIFO, impedance, interrupt와 downshift 초기화
Linux RTL8211F driver
paged register, RGMII TX/RX delay, ALDPS, CLKOUT, EEE, WOL과 interrupt 처리
Microchip LAN8841 product and datasheet
RGMII, IEEE 1588v2, cable diagnostics와 제조사 데이터시트
Linux LAN8841 driver in micrel.c
KSZ9131 공통 초기화, LAN8841 errata, PTP, interrupt와 cable test 경로
06 · REGISTERS
읽어야 할 상태와 해석
값 하나만 떼어 보지 말고 동일 사건의 enable, status, ownership, completion register를 한 줄에 기록합니다. read-to-clear나 write-one-to-clear 속성은 반드시 datasheet에서 먼저 확인합니다.
| 레지스터/상태 | 소유 블록 | 검증할 의미 |
|---|---|---|
| BMCR | Clause 22 reg 0 | reset, autoneg enable/restart, speed/duplex control |
| BMSR | Clause 22 reg 1 | link, AN complete, capability와 latch-low 처리 |
| PHYID1/2 | reg 2/3 | MDIO address와 PHY driver match |
| ANAR/ANLPAR | reg 4/5 | local/partner 10/100과 pause advertisement |
| 1000BASE-T Ctrl/Stat | reg 9/10 | 1000 capability와 master/slave resolution |
| MAC/PCS status | MAC specific | resolved speed/duplex와 interface clock 상태 |
07 · LINUX SOURCE
Linux v6.18.37 원본 코드와 줄별 해설
라인 번호를 고정해 외우는 대신 함수 선언을 기준으로 Linux v6.18.37 tree에서 다시 찾았습니다. 로컬 tree에 있는 파일은 실제 코드를 직접 싣고, 나머지는 원본 파일과 읽을 함수 좌표를 연결했습니다.
Linux v6.18.37 · 실제 원본 코드
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로
drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c:569-639
569 priv->gmii_address_bus_config = value & priv->hw->mii.clk_csr_mask;
570}
571
572/**
573 * stmmac_mdio_register
574 * @ndev: net device structure
575 * Description: it registers the MII bus
576 */
577int stmmac_mdio_register(struct net_device *ndev)
578{
579 int err = 0;
580 struct mii_bus *new_bus;
581 struct stmmac_priv *priv = netdev_priv(ndev);
582 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
583 struct device_node *mdio_node = priv->plat->mdio_node;
584 struct device *dev = ndev->dev.parent;
585 struct fwnode_handle *fixed_node;
586 struct fwnode_handle *fwnode;
587 int addr, found, max_addr;
588
589 if (!mdio_bus_data)
590 return 0;
591
592 stmmac_mdio_bus_config(priv);
593
594 new_bus = mdiobus_alloc();
595 if (!new_bus)
596 return -ENOMEM;
597
598 if (mdio_bus_data->irqs)
599 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
600
601 new_bus->name = "stmmac";
602
603 if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
604 new_bus->read = &stmmac_xgmac2_mdio_read_c22;
605 new_bus->write = &stmmac_xgmac2_mdio_write_c22;
606 new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45;
607 new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45;
608
609 if (priv->synopsys_id < DWXGMAC_CORE_2_20) {
610 /* Right now only C22 phys are supported */
611 max_addr = MII_XGMAC_MAX_C22ADDR + 1;
612
613 /* Check if DT specified an unsupported phy addr */
614 if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)
615 dev_err(dev, "Unsupported phy_addr (max=%d)\n",
616 MII_XGMAC_MAX_C22ADDR);
617 } else {
618 /* XGMAC version 2.20 onwards support 32 phy addr */
619 max_addr = PHY_MAX_ADDR;
620 }
621 } else {
622 new_bus->read = &stmmac_mdio_read_c22;
623 new_bus->write = &stmmac_mdio_write_c22;
624 if (priv->plat->core_type == DWMAC_CORE_GMAC4) {
625 new_bus->read_c45 = &stmmac_mdio_read_c45;
626 new_bus->write_c45 = &stmmac_mdio_write_c45;
627 }
628
629 max_addr = PHY_MAX_ADDR;
630 }
631
632 if (mdio_bus_data->needs_reset)
633 new_bus->reset = &stmmac_mdio_reset;
634
635 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
636 new_bus->name, priv->plat->bus_id);
637 new_bus->priv = ndev;
638 new_bus->phy_mask = mdio_bus_data->phy_mask | mdio_bus_data->pcs_mask;
639 new_bus->parent = priv->device;priv->gmii_address_bus_config = value & priv->hw->mii.clk_csr_mask;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/**
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* stmmac_mdio_register
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* @ndev: net device structure
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* Description: it registers the MII bus
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
int stmmac_mdio_register(struct net_device *ndev)
함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 입력 계약을 만족하는지 확인합니다.
{
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
int err = 0;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct mii_bus *new_bus;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct stmmac_priv *priv = netdev_priv(ndev);
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct device_node *mdio_node = priv->plat->mdio_node;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct device *dev = ndev->dev.parent;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct fwnode_handle *fixed_node;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct fwnode_handle *fwnode;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
int addr, found, max_addr;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (!mdio_bus_data)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
return 0;
호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
stmmac_mdio_bus_config(priv);
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
new_bus = mdiobus_alloc();
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
if (!new_bus)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
return -ENOMEM;
호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (mdio_bus_data->irqs)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
new_bus->name = "stmmac";
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
new_bus->read = &stmmac_xgmac2_mdio_read_c22;
공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.
new_bus->write = &stmmac_xgmac2_mdio_write_c22;
hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.
new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45;
공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.
new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45;
hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (priv->synopsys_id < DWXGMAC_CORE_2_20) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
/* Right now only C22 phys are supported */
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
max_addr = MII_XGMAC_MAX_C22ADDR + 1;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* Check if DT specified an unsupported phy addr */
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
dev_err(dev, "Unsupported phy_addr (max=%d)\n",
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
MII_XGMAC_MAX_C22ADDR);
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
} else {
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
/* XGMAC version 2.20 onwards support 32 phy addr */
원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
max_addr = PHY_MAX_ADDR;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
} else {
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
new_bus->read = &stmmac_mdio_read_c22;
공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.
new_bus->write = &stmmac_mdio_write_c22;
hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.
if (priv->plat->core_type == DWMAC_CORE_GMAC4) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
new_bus->read_c45 = &stmmac_mdio_read_c45;
공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.
new_bus->write_c45 = &stmmac_mdio_write_c45;
hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
max_addr = PHY_MAX_ADDR;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (mdio_bus_data->needs_reset)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
new_bus->reset = &stmmac_mdio_reset;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
new_bus->name, priv->plat->bus_id);
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
new_bus->priv = ndev;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
new_bus->phy_mask = mdio_bus_data->phy_mask | mdio_bus_data->pcs_mask;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
new_bus->parent = priv->device;
stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
Linux v6.18.37 · 실제 원본 코드
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로
drivers/net/phy/phylink.c:987-1057
987
988 if (pcs->ops->pcs_pre_init)
989 ret = pcs->ops->pcs_pre_init(pcs);
990
991 return ret;
992}
993EXPORT_SYMBOL_GPL(phylink_pcs_pre_init);
994
995static void phylink_mac_config(struct phylink *pl,
996 const struct phylink_link_state *state)
997{
998 struct phylink_link_state st = *state;
999
1000 /* Stop drivers incorrectly using these */
1001 linkmode_zero(st.lp_advertising);
1002 st.speed = SPEED_UNKNOWN;
1003 st.duplex = DUPLEX_UNKNOWN;
1004 st.an_complete = false;
1005 st.link = false;
1006
1007 phylink_dbg(pl,
1008 "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n",
1009 __func__, phylink_an_mode_str(pl->act_link_an_mode),
1010 phy_modes(st.interface),
1011 phy_rate_matching_to_str(st.rate_matching),
1012 __ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising,
1013 st.pause);
1014
1015 pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st);
1016}
1017
1018static void phylink_pcs_an_restart(struct phylink *pl)
1019{
1020 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
1021 pl->link_config.advertising) &&
1022 phy_interface_mode_is_8023z(pl->link_config.interface) &&
1023 phylink_autoneg_inband(pl->act_link_an_mode))
1024 pl->pcs->ops->pcs_an_restart(pl->pcs);
1025}
1026
1027enum inband_type {
1028 INBAND_NONE,
1029 INBAND_CISCO_SGMII,
1030 INBAND_BASEX,
1031};
1032
1033static enum inband_type phylink_get_inband_type(phy_interface_t interface)
1034{
1035 switch (interface) {
1036 case PHY_INTERFACE_MODE_SGMII:
1037 case PHY_INTERFACE_MODE_QSGMII:
1038 case PHY_INTERFACE_MODE_QUSGMII:
1039 case PHY_INTERFACE_MODE_USXGMII:
1040 case PHY_INTERFACE_MODE_10G_QXGMII:
1041 /* These protocols are designed for use with a PHY which
1042 * communicates its negotiation result back to the MAC via
1043 * inband communication. Note: there exist PHYs that run
1044 * with SGMII but do not send the inband data.
1045 */
1046 return INBAND_CISCO_SGMII;
1047
1048 case PHY_INTERFACE_MODE_1000BASEX:
1049 case PHY_INTERFACE_MODE_2500BASEX:
1050 /* 1000base-X is designed for use media-side for Fibre
1051 * connections, and thus the Autoneg bit needs to be
1052 * taken into account. We also do this for 2500base-X
1053 * as well, but drivers may not support this, so may
1054 * need to override this.
1055 */
1056 return INBAND_BASEX;
1057 (blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (pcs->ops->pcs_pre_init)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
ret = pcs->ops->pcs_pre_init(pcs);
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
return ret;
호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
EXPORT_SYMBOL_GPL(phylink_pcs_pre_init);
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
static void phylink_mac_config(struct phylink *pl,
함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 입력 계약을 만족하는지 확인합니다.
const struct phylink_link_state *state)
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
{
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
struct phylink_link_state st = *state;
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* Stop drivers incorrectly using these */
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
linkmode_zero(st.lp_advertising);
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
st.speed = SPEED_UNKNOWN;
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
st.duplex = DUPLEX_UNKNOWN;
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
st.an_complete = false;
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
st.link = false;
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
phylink_dbg(pl,
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
"%s: mode=%s/%s/%s adv=%*pb pause=%02x\n",
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
__func__, phylink_an_mode_str(pl->act_link_an_mode),
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phy_modes(st.interface),
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phy_rate_matching_to_str(st.rate_matching),
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
__ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising,
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
st.pause);
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st);
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
static void phylink_pcs_an_restart(struct phylink *pl)
함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 입력 계약을 만족하는지 확인합니다.
{
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
pl->link_config.advertising) &&
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phy_interface_mode_is_8023z(pl->link_config.interface) &&
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phylink_autoneg_inband(pl->act_link_an_mode))
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
pl->pcs->ops->pcs_an_restart(pl->pcs);
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
enum inband_type {
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
INBAND_NONE,
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
INBAND_CISCO_SGMII,
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
INBAND_BASEX,
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
};
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
static enum inband_type phylink_get_inband_type(phy_interface_t interface)
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
{
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
switch (interface) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
case PHY_INTERFACE_MODE_SGMII:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
case PHY_INTERFACE_MODE_QSGMII:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
case PHY_INTERFACE_MODE_QUSGMII:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
case PHY_INTERFACE_MODE_USXGMII:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
case PHY_INTERFACE_MODE_10G_QXGMII:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
/* These protocols are designed for use with a PHY which
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* communicates its negotiation result back to the MAC via
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* inband communication. Note: there exist PHYs that run
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* with SGMII but do not send the inband data.
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
return INBAND_CISCO_SGMII;
호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
case PHY_INTERFACE_MODE_1000BASEX:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
case PHY_INTERFACE_MODE_2500BASEX:
resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
/* 1000base-X is designed for use media-side for Fibre
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* connections, and thus the Autoneg bit needs to be
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* taken into account. We also do this for 2500base-X
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* as well, but drivers may not support this, so may
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* need to override this.
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
return INBAND_BASEX;
호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
Linux v6.18.37 · 실제 원본 코드
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work
drivers/net/phy/phylink.c:1593-1675
1593 phylink_info(pl, "Link is Down\n");
1594}
1595
1596static bool phylink_link_is_up(struct phylink *pl)
1597{
1598 return pl->netdev ? netif_carrier_ok(pl->netdev) : pl->old_link_state;
1599}
1600
1601static void phylink_resolve(struct work_struct *w)
1602{
1603 struct phylink *pl = container_of(w, struct phylink, resolve);
1604 struct phylink_link_state link_state;
1605 bool mac_config = false;
1606 bool retrigger = false;
1607 struct phy_device *phy;
1608 bool cur_link_state;
1609
1610 mutex_lock(&pl->phydev_mutex);
1611 phy = pl->phydev;
1612 if (phy)
1613 mutex_lock(&phy->lock);
1614 mutex_lock(&pl->state_mutex);
1615 cur_link_state = phylink_link_is_up(pl);
1616
1617 if (pl->phylink_disable_state) {
1618 pl->link_failed = false;
1619 link_state.link = false;
1620 } else if (pl->link_failed) {
1621 link_state.link = false;
1622 retrigger = true;
1623 } else if (pl->act_link_an_mode == MLO_AN_FIXED) {
1624 phylink_get_fixed_state(pl, &link_state);
1625 mac_config = link_state.link;
1626 } else if (pl->act_link_an_mode == MLO_AN_PHY) {
1627 link_state = pl->phy_state;
1628 mac_config = link_state.link;
1629 } else {
1630 phylink_mac_pcs_get_state(pl, &link_state);
1631
1632 /* The PCS may have a latching link-fail indicator. If the link
1633 * was up, bring the link down and re-trigger the resolve.
1634 * Otherwise, re-read the PCS state to get the current status
1635 * of the link.
1636 */
1637 if (!link_state.link) {
1638 if (cur_link_state)
1639 retrigger = true;
1640 else
1641 phylink_mac_pcs_get_state(pl, &link_state);
1642 }
1643
1644 /* If we have a phy, the "up" state is the union of both the
1645 * PHY and the MAC
1646 */
1647 if (phy)
1648 link_state.link &= pl->phy_state.link;
1649
1650 /* Only update if the PHY link is up */
1651 if (phy && pl->phy_state.link) {
1652 /* If the interface has changed, force a link down
1653 * event if the link isn't already down, and re-resolve.
1654 */
1655 if (link_state.interface != pl->phy_state.interface) {
1656 retrigger = true;
1657 link_state.link = false;
1658 }
1659
1660 link_state.interface = pl->phy_state.interface;
1661
1662 /* If we are doing rate matching, then the link
1663 * speed/duplex comes from the PHY
1664 */
1665 if (pl->phy_state.rate_matching) {
1666 link_state.rate_matching =
1667 pl->phy_state.rate_matching;
1668 link_state.speed = pl->phy_state.speed;
1669 link_state.duplex = pl->phy_state.duplex;
1670 }
1671
1672 /* If we have a PHY, we need to update with the PHY
1673 * flow control bits.
1674 */
1675 link_state.pause = pl->phy_state.pause;phylink_info(pl, "Link is Down\n");
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
static bool phylink_link_is_up(struct phylink *pl)
함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 입력 계약을 만족하는지 확인합니다.
{
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
return pl->netdev ? netif_carrier_ok(pl->netdev) : pl->old_link_state;
호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
static void phylink_resolve(struct work_struct *w)
함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 입력 계약을 만족하는지 확인합니다.
{
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
struct phylink *pl = container_of(w, struct phylink, resolve);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct phylink_link_state link_state;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
bool mac_config = false;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
bool retrigger = false;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
struct phy_device *phy;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
bool cur_link_state;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
mutex_lock(&pl->phydev_mutex);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phy = pl->phydev;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
if (phy)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
mutex_lock(&phy->lock);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
mutex_lock(&pl->state_mutex);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
cur_link_state = phylink_link_is_up(pl);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
if (pl->phylink_disable_state) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
pl->link_failed = false;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
link_state.link = false;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
} else if (pl->link_failed) {
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
link_state.link = false;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
retrigger = true;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
} else if (pl->act_link_an_mode == MLO_AN_FIXED) {
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phylink_get_fixed_state(pl, &link_state);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
mac_config = link_state.link;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
} else if (pl->act_link_an_mode == MLO_AN_PHY) {
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
link_state = pl->phy_state;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
mac_config = link_state.link;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
} else {
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phylink_mac_pcs_get_state(pl, &link_state);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* The PCS may have a latching link-fail indicator. If the link
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* was up, bring the link down and re-trigger the resolve.
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* Otherwise, re-read the PCS state to get the current status
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* of the link.
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
if (!link_state.link) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
if (cur_link_state)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
retrigger = true;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
else
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
phylink_mac_pcs_get_state(pl, &link_state);
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* If we have a phy, the "up" state is the union of both the
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* PHY and the MAC
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
if (phy)
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
link_state.link &= pl->phy_state.link;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* Only update if the PHY link is up */
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
if (phy && pl->phy_state.link) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
/* If the interface has changed, force a link down
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* event if the link isn't already down, and re-resolve.
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
if (link_state.interface != pl->phy_state.interface) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
retrigger = true;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
link_state.link = false;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
link_state.interface = pl->phy_state.interface;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* If we are doing rate matching, then the link
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* speed/duplex comes from the PHY
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
if (pl->phy_state.rate_matching) {
상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.
link_state.rate_matching =
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
pl->phy_state.rate_matching;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
link_state.speed = pl->phy_state.speed;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
link_state.duplex = pl->phy_state.duplex;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
}
제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.
(blank)
논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.
/* If we have a PHY, we need to update with the PHY
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
* flow control bits.
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
*/
원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.
link_state.pause = pl->phy_state.pause;
PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.
Linux v6.18.37 · 원본 좌표
Documentation/devicetree/bindings/net/ethernet-controller.yaml
board wiring을 Linux firmware description으로 옮기는 binding
- 읽을 함수
phy-mode- 읽을 함수
phy-handle- 읽을 함수
fixed-link
08 · VERIFICATION
실제 장비에서 확인하는 순서
- Electrical
실행 reset, MDC/MDIO와 RGMII/SGMII clock를 계측한다.
통과 기준 datasheet timing과 voltage, MDC period가 범위 안이어야 한다.
- PHY
실행 BMCR/BMSR/PHY ID와 AN advertisement를 raw로 저장한다.
통과 기준 `ethtool` 결과가 raw resolution과 일치해야 한다.
- Interface
실행 RGMII delay 설정과 실제 clock-data skew를 확인한다.
통과 기준 delay가 0회 또는 정확히 1회 적용돼야 한다.
- Linux
실행 `ethtool -S`와 `ip -s link`를 traffic 전후 비교한다.
통과 기준 good frame과 error counter의 증가 위치로 PHY/MAC/DMA를 나눈다.
- Corner
실행 cold boot, warm reset, cable reconnect, 10/100/1000 peer를 반복한다.
통과 기준 각 mode 전환에서 carrier와 MAC mode가 같은 값으로 수렴해야 한다.
09 · FAILURE MATRIX
처음 끊긴 경계로 원인을 좁히기
| 관측 결과 | 우선 의심할 경계 | 다음 증거 |
|---|---|---|
| PHY ID 0xffff | MDIO pull-up/address/clock/reset 문제 | logic analyzer와 PHY reset |
| AN complete 안 됨 | cable/pair/advertisement/master-slave 문제 | BMSR, partner ability, PHY diagnostics |
| carrier는 ON, CRC 폭증 | RGMII delay/clock edge/MAC mode 불일치 | MAC CRC와 PHY symbol error 비교 |
| 한 속도에서만 실패 | interface clock 또는 pair/SI margin 문제 | 속도별 clock와 error counter |
| link flap | power/clock, EEE, PHY interrupt 또는 cable margin | state timestamp와 raw PHY status |
핵심은 마지막 오류 메시지가 아니라 처음 기대값과 달라진 checkpoint입니다. 그보다 아래의 통과 증거와 그 지점의 실패 증거를 한 묶음으로 남겨야 수정의 효과도 검증할 수 있습니다.