← HardwareDUJINLABS.COM

Hardware 03 · Ethernet · Linux v6.18.37

Ethernet PHY, MDIO, Auto-Negotiation과 MAC

RJ45/magnetics와 MDI electrical 상태에서 PHY reset, MDIO register, auto-negotiation, RGMII/SGMII timing과 Linux phylib/phylink까지 올라갑니다.

검증 깊이
board → Linux 8 layers
그림
4 boundary diagrams
원본 코드
3 excerpts · 225 lines
기준
Linux v6.18.37

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단계

그림 1. 아래에서 Linux까지 올라오는 8개 검증 경계위 계층의 로그보다 아래 계층의 물리 증거를 먼저 확정합니다.
01
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

START
02
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

CHECKPOINT
03
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 결과

CHECKPOINT
04
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

CHECKPOINT
05
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

CHECKPOINT
06
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

CHECKPOINT
07
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

CHECKPOINT
08
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

LINUX / RESULT
01

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가 정상이라는 증거가 아니다.

02

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도 시작되지 않는다.

03

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 특성이 있을 수 있어 두 번 읽는 규칙을 확인한다.

04

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를 함께 본다.

05

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를 먼저 의심한다.

06

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 설정을 대조한다.

07

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까지 도달하는지 확인한다.

08

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

주소와 상태가 이동하는 모습

그림 2. Ethernet 실행 경로왼쪽에서 오른쪽으로 실제 소유권과 관찰 지점이 이동합니다.
01 Rail/clock
02 Reset release
03 MDIO ID
04 Advertisement
05 AN complete
06 PHY link
그림 3. firmware와 Linux 번호 공간의 연결왼쪽에서 오른쪽으로 실제 소유권과 관찰 지점이 이동합니다.
01 PHY resolved mode
02 phylink validate
03 MAC config
04 PCS sync
05 MAC link_up
06 carrier on
그림 4. 입력, 소유권, 완료 조건의 경계완료 조건을 충족하기 전에는 다음 계층이 해당 자원을 재사용하면 안 됩니다.
INPUT

PHY 전원과 reference clock, reset, magnetics/connector, MAC-PHY interface와 MDIO bus

OWNER

PHY는 line link와 negotiation, MAC은 frame/DMA, phylib/phylink는 두 hardware state의 Linux 동기화를 소유

OUTPUT

speed/duplex/pause가 합의되고 MAC clock와 datapath가 같은 mode로 설정된 carrier-on net_device

DONE

`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 phylink

PHY, fixed-link, in-band PCS와 MAC callback의 관계

06 · REGISTERS

읽어야 할 상태와 해석

값 하나만 떼어 보지 말고 동일 사건의 enable, status, ownership, completion register를 한 줄에 기록합니다. read-to-clear나 write-one-to-clear 속성은 반드시 datasheet에서 먼저 확인합니다.

레지스터/상태소유 블록검증할 의미
BMCRClause 22 reg 0reset, autoneg enable/restart, speed/duplex control
BMSRClause 22 reg 1link, AN complete, capability와 latch-low 처리
PHYID1/2reg 2/3MDIO address와 PHY driver match
ANAR/ANLPARreg 4/5local/partner 10/100과 pause advertisement
1000BASE-T Ctrl/Statreg 9/101000 capability와 master/slave resolution
MAC/PCS statusMAC specificresolved 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;
L569 priv->gmii_address_bus_config = value & priv->hw->mii.clk_csr_mask;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L570 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L571 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L572 /**

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L573 * stmmac_mdio_register

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L574 * @ndev: net device structure

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L575 * Description: it registers the MII bus

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L576 */

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L577 int stmmac_mdio_register(struct net_device *ndev)

함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 입력 계약을 만족하는지 확인합니다.

L578 {

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L579 int err = 0;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L580 struct mii_bus *new_bus;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L581 struct stmmac_priv *priv = netdev_priv(ndev);

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L582 struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L583 struct device_node *mdio_node = priv->plat->mdio_node;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L584 struct device *dev = ndev->dev.parent;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L585 struct fwnode_handle *fixed_node;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L586 struct fwnode_handle *fwnode;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L587 int addr, found, max_addr;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L588 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L589 if (!mdio_bus_data)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L590 return 0;

호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.

L591 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L592 stmmac_mdio_bus_config(priv);

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L593 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L594 new_bus = mdiobus_alloc();

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L595 if (!new_bus)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L596 return -ENOMEM;

호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.

L597 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L598 if (mdio_bus_data->irqs)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L599 memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L600 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L601 new_bus->name = "stmmac";

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L602 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L603 if (priv->plat->core_type == DWMAC_CORE_XGMAC) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L604 new_bus->read = &stmmac_xgmac2_mdio_read_c22;

공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.

L605 new_bus->write = &stmmac_xgmac2_mdio_write_c22;

hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.

L606 new_bus->read_c45 = &stmmac_xgmac2_mdio_read_c45;

공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.

L607 new_bus->write_c45 = &stmmac_xgmac2_mdio_write_c45;

hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.

L608 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L609 if (priv->synopsys_id < DWXGMAC_CORE_2_20) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L610 /* Right now only C22 phys are supported */

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L611 max_addr = MII_XGMAC_MAX_C22ADDR + 1;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L612 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L613 /* Check if DT specified an unsupported phy addr */

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L614 if (priv->plat->phy_addr > MII_XGMAC_MAX_C22ADDR)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L615 dev_err(dev, "Unsupported phy_addr (max=%d)\n",

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L616 MII_XGMAC_MAX_C22ADDR);

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L617 } else {

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L618 /* XGMAC version 2.20 onwards support 32 phy addr */

원본 주석입니다. stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L619 max_addr = PHY_MAX_ADDR;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L620 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L621 } else {

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L622 new_bus->read = &stmmac_mdio_read_c22;

공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.

L623 new_bus->write = &stmmac_mdio_write_c22;

hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.

L624 if (priv->plat->core_type == DWMAC_CORE_GMAC4) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L625 new_bus->read_c45 = &stmmac_mdio_read_c45;

공유 상태나 MMIO를 읽습니다. 이 값은 단순 변수라기보다 hardware가 갱신한 시점과 read ordering을 포함해 해석해야 합니다.

L626 new_bus->write_c45 = &stmmac_mdio_write_c45;

hardware 또는 공유 메모리에 상태를 게시합니다. write가 완료되는 지점과 다음 read/doorbell 사이의 ordering 조건을 확인합니다.

L627 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L628 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L629 max_addr = PHY_MAX_ADDR;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L630 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L631 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L632 if (mdio_bus_data->needs_reset)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L633 new_bus->reset = &stmmac_mdio_reset;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L634 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L635 snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L636 new_bus->name, priv->plat->bus_id);

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L637 new_bus->priv = ndev;

stmmac이 MDIO bus를 만들고 firmware node의 PHY를 등록하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L638 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와 연결해 확인합니다.

L639 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 
L987 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L988 if (pcs->ops->pcs_pre_init)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L989 ret = pcs->ops->pcs_pre_init(pcs);

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L990 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L991 return ret;

호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.

L992 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L993 EXPORT_SYMBOL_GPL(phylink_pcs_pre_init);

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L994 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L995 static void phylink_mac_config(struct phylink *pl,

함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 입력 계약을 만족하는지 확인합니다.

L996 const struct phylink_link_state *state)

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L997 {

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L998 struct phylink_link_state st = *state;

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L999 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1000 /* Stop drivers incorrectly using these */

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1001 linkmode_zero(st.lp_advertising);

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1002 st.speed = SPEED_UNKNOWN;

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1003 st.duplex = DUPLEX_UNKNOWN;

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1004 st.an_complete = false;

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1005 st.link = false;

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1006 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1007 phylink_dbg(pl,

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1008 "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n",

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1009 __func__, phylink_an_mode_str(pl->act_link_an_mode),

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1010 phy_modes(st.interface),

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1011 phy_rate_matching_to_str(st.rate_matching),

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1012 __ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising,

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1013 st.pause);

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1014 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1015 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와 연결해 확인합니다.

L1016 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1017 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1018 static void phylink_pcs_an_restart(struct phylink *pl)

함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 입력 계약을 만족하는지 확인합니다.

L1019 {

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1020 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1021 pl->link_config.advertising) &&

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1022 phy_interface_mode_is_8023z(pl->link_config.interface) &&

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1023 phylink_autoneg_inband(pl->act_link_an_mode))

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1024 pl->pcs->ops->pcs_an_restart(pl->pcs);

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1025 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1026 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1027 enum inband_type {

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1028 INBAND_NONE,

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1029 INBAND_CISCO_SGMII,

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1030 INBAND_BASEX,

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1031 };

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1032 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1033 static enum inband_type phylink_get_inband_type(phy_interface_t interface)

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1034 {

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1035 switch (interface) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1036 case PHY_INTERFACE_MODE_SGMII:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1037 case PHY_INTERFACE_MODE_QSGMII:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1038 case PHY_INTERFACE_MODE_QUSGMII:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1039 case PHY_INTERFACE_MODE_USXGMII:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1040 case PHY_INTERFACE_MODE_10G_QXGMII:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1041 /* These protocols are designed for use with a PHY which

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1042 * communicates its negotiation result back to the MAC via

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1043 * inband communication. Note: there exist PHYs that run

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1044 * with SGMII but do not send the inband data.

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1045 */

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1046 return INBAND_CISCO_SGMII;

호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.

L1047 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1048 case PHY_INTERFACE_MODE_1000BASEX:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1049 case PHY_INTERFACE_MODE_2500BASEX:

resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1050 /* 1000base-X is designed for use media-side for Fibre

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1051 * connections, and thus the Autoneg bit needs to be

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1052 * taken into account. We also do this for 2500base-X

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1053 * as well, but drivers may not support this, so may

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1054 * need to override this.

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1055 */

원본 주석입니다. resolved PHY/PCS state를 MAC configuration callback으로 전달하는 경로에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1056 return INBAND_BASEX;

호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.

L1057 (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;
L1593 phylink_info(pl, "Link is Down\n");

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1594 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1595 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1596 static bool phylink_link_is_up(struct phylink *pl)

함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 입력 계약을 만족하는지 확인합니다.

L1597 {

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1598 return pl->netdev ? netif_carrier_ok(pl->netdev) : pl->old_link_state;

호출자에게 상태를 반환합니다. 반환값만 보지 말고 그 전에 controller ownership이나 active 상태가 정리되었는지 확인합니다.

L1599 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1600 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1601 static void phylink_resolve(struct work_struct *w)

함수 경계입니다. 호출자가 넘긴 번호 공간과 현재 CPU/controller context가 PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 입력 계약을 만족하는지 확인합니다.

L1602 {

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1603 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와 연결해 확인합니다.

L1604 struct phylink_link_state link_state;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1605 bool mac_config = false;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1606 bool retrigger = false;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1607 struct phy_device *phy;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1608 bool cur_link_state;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1609 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1610 mutex_lock(&pl->phydev_mutex);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1611 phy = pl->phydev;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1612 if (phy)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1613 mutex_lock(&phy->lock);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1614 mutex_lock(&pl->state_mutex);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1615 cur_link_state = phylink_link_is_up(pl);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1616 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1617 if (pl->phylink_disable_state) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1618 pl->link_failed = false;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1619 link_state.link = false;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1620 } else if (pl->link_failed) {

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1621 link_state.link = false;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1622 retrigger = true;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1623 } 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와 연결해 확인합니다.

L1624 phylink_get_fixed_state(pl, &link_state);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1625 mac_config = link_state.link;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1626 } 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와 연결해 확인합니다.

L1627 link_state = pl->phy_state;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1628 mac_config = link_state.link;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1629 } else {

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1630 phylink_mac_pcs_get_state(pl, &link_state);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1631 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1632 /* The PCS may have a latching link-fail indicator. If the link

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1633 * was up, bring the link down and re-trigger the resolve.

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1634 * Otherwise, re-read the PCS state to get the current status

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1635 * of the link.

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1636 */

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1637 if (!link_state.link) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1638 if (cur_link_state)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1639 retrigger = true;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1640 else

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1641 phylink_mac_pcs_get_state(pl, &link_state);

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1642 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1643 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1644 /* 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에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1645 * PHY and the MAC

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1646 */

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1647 if (phy)

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1648 link_state.link &= pl->phy_state.link;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1649 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1650 /* Only update if the PHY link is up */

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1651 if (phy && pl->phy_state.link) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1652 /* If the interface has changed, force a link down

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1653 * event if the link isn't already down, and re-resolve.

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1654 */

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1655 if (link_state.interface != pl->phy_state.interface) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1656 retrigger = true;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1657 link_state.link = false;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1658 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1659 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1660 link_state.interface = pl->phy_state.interface;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1661 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1662 /* If we are doing rate matching, then the link

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1663 * speed/duplex comes from the PHY

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1664 */

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1665 if (pl->phy_state.rate_matching) {

상태나 ID를 분류하는 분기입니다. 이 조건의 참·거짓은 장치 register, firmware 기술 또는 CPU mode 중 하나에서 결정됩니다.

L1666 link_state.rate_matching =

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1667 pl->phy_state.rate_matching;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1668 link_state.speed = pl->phy_state.speed;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1669 link_state.duplex = pl->phy_state.duplex;

PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work의 한 단계입니다. 이 줄이 바꾸는 software 상태를 대응하는 controller register나 trace checkpoint와 연결해 확인합니다.

L1670 }

제어 블록의 범위를 표시합니다. 이 괄호 안에서만 유효한 lock, CPU context, resource lifetime을 함께 표시해 둡니다.

L1671 (blank)

논리 구간을 나누는 빈 줄입니다. 바로 위에서 준비한 상태와 다음 제어 흐름을 분리해 읽습니다.

L1672 /* If we have a PHY, we need to update with the PHY

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1673 * flow control bits.

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1674 */

원본 주석입니다. PHY, fixed-link 또는 in-band PCS 상태를 resolve하고 link up/down을 결정하는 work에서 뒤따르는 코드가 전제하는 하드웨어 조건이나 예외를 먼저 확인합니다.

L1675 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

Linux v6.18.37 원본 파일 열기 →

08 · VERIFICATION

실제 장비에서 확인하는 순서

  1. Electrical

    실행 reset, MDC/MDIO와 RGMII/SGMII clock를 계측한다.

    통과 기준 datasheet timing과 voltage, MDC period가 범위 안이어야 한다.

  2. PHY

    실행 BMCR/BMSR/PHY ID와 AN advertisement를 raw로 저장한다.

    통과 기준 `ethtool` 결과가 raw resolution과 일치해야 한다.

  3. Interface

    실행 RGMII delay 설정과 실제 clock-data skew를 확인한다.

    통과 기준 delay가 0회 또는 정확히 1회 적용돼야 한다.

  4. Linux

    실행 `ethtool -S`와 `ip -s link`를 traffic 전후 비교한다.

    통과 기준 good frame과 error counter의 증가 위치로 PHY/MAC/DMA를 나눈다.

  5. Corner

    실행 cold boot, warm reset, cable reconnect, 10/100/1000 peer를 반복한다.

    통과 기준 각 mode 전환에서 carrier와 MAC mode가 같은 값으로 수렴해야 한다.

09 · FAILURE MATRIX

처음 끊긴 경계로 원인을 좁히기

관측 결과우선 의심할 경계다음 증거
PHY ID 0xffffMDIO 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 flappower/clock, EEE, PHY interrupt 또는 cable marginstate timestamp와 raw PHY status

핵심은 마지막 오류 메시지가 아니라 처음 기대값과 달라진 checkpoint입니다. 그보다 아래의 통과 증거와 그 지점의 실패 증거를 한 묶음으로 남겨야 수정의 효과도 검증할 수 있습니다.