Pull to refresh

Включение отображения flow-control в ethtool's

Приветствую всех.

Хочу рассказать про небольшую доработку (4 строчки), которая в итоге дошла до патча, который приняли в следующий релиз ядра Linux.

Началось все с того, как меня попросили включить Flow-control в камере, которая работает под управлением встроенной ОС, на ядре Linux. Естественно мне было необходима возможность проверить на своем ноутбуке включилась таки или нет эта опция.

Такая информация может быть получена через инструменты командной строки ethtool и mii-tool. При этом вторая (mii-tool) во многих интернет-источниках (на форумах на которых я смотрел) указывалась как устаревшая.

Я естественно попробовал обе и вот какие результаты получил:
root@thinkpad:~# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Advertised pause frame use: No
Advertised auto-negotiation: Yes
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Link partner advertised pause frame use: No
Link partner advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: pumbg
Wake-on: g
Current message level: 0x00000033 (51)
Link detected: yes


а для mii-tool:
root@artpol-thinkpad:~# mii-tool eth0
eth0: negotiated 100baseTx-FD flow-control, link ok

root@artpol-thinkpad:~# mii-tool -v eth0
eth0: negotiated 100baseTx-FD flow-control, link ok
product info: vendor 00:07:32, model 17 rev 2
basic mode: autonegotiation enabled
basic status: autonegotiation complete, link ok
capabilities: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD
advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control
link partner: 1000baseT-HD 1000baseT-FD 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD flow-control


Обратите внимание, что результаты этих утилит в части flow-control очевидно конфликтуют.

А так как мне было необходимо все-таки выяснить включился ли flow-control на link partner (встроенном Linux-е в камере), то я полез в исходные коды ethtool и Linux kernel на своем ноутбуке. В итоге получилась такая расстановка сил:

image

r8169.c — это драйвер моей сетевой карточки.
Причина неправильного отображения оказалась в функции mii_get_an (выделена на рисунке):

static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
{
u32 result = 0;
int advert;

advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
if (advert & LPA_LPACK)
result |= ADVERTISED_Autoneg;
if (advert & ADVERTISE_10HALF)
result |= ADVERTISED_10baseT_Half;
if (advert & ADVERTISE_10FULL)
result |= ADVERTISED_10baseT_Full;
if (advert & ADVERTISE_100HALF)
result |= ADVERTISED_100baseT_Half;
if (advert & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;

return result;
}


Функция mdio_read (являющаяся указателем на функцию r8169_mdio_read) возвращает правильные значения MII регистров, в которых указывается, в частности, информация о flow-control. Однако в mii_get_an нужные значения не обрабатываются. Изменение указанной функции следующим образом:

static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
{
u32 result = 0;
int advert;

advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
if (advert & LPA_LPACK)
result |= ADVERTISED_Autoneg;
if (advert & ADVERTISE_10HALF)
result |= ADVERTISED_10baseT_Half;
if (advert & ADVERTISE_10FULL)
result |= ADVERTISED_10baseT_Full;
if (advert & ADVERTISE_100HALF)
result |= ADVERTISED_100baseT_Half;
if (advert & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;
if (advert & ADVERTISE_PAUSE_CAP)
result |= ADVERTISED_Pause;
if (advert & ADVERTISE_PAUSE_ASYM)
result |= ADVERTISED_Asym_Pause;


return result;
}


компиляция ядра и соответствующих модулей позволила получить ту информацию, которой мне так недоставало:

root@thinkpad:~# ethtool eth0
Settings for eth0:
Supported ports: [ TP MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Half 1000baseT/Full
Advertised pause frame use: Symmetric Receive-only
Advertised auto-negotiation: Yes
Link partner advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
Link partner advertised pause frame use: Symmetric
Link partner advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
Supports Wake-on: pumbg
Wake-on: g
Current message level: 0x00000033 (51)
Link detected: yes


Анализ ядер linux различных версий показал что эта проблема была достаточно давно, но по-идее в следующие версии описанные изменения должны войти.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.