
phy_read
метод в /include/linux/phy.h возвращает 32-битное значение. Драйверы phy используют этот метод для чтения регистров MII, которые являются 16-битными. phy_read
метод возвращает 32-битное значение. сохранение 16-битного значения в 32-битном поле делает 0xFFFF как 0x0000FFFF, в 16-битном поле это было бы расценено как -1 (ошибка) и обработано таким образом, но сохранение этого в 32-битном поле делает его большим положительным значением, а не ошибкой. Это изменяет ход выполнения драйвера и создает изменения параметров связи нежелательным образом.
Я наблюдал это для genphy_read_status
метода, где значение возвращается phy_read
is и int (4 байта), однако оно содержит 0xFFFF в случае, если строки управления удалены или произошла какая-то ошибка. Поскольку возвращаемое значение составляет 4 байта, все проверки, которые проверяют, меньше ли оно нуля, терпят неудачу. В таком сценарии скорость связи и дублирование изменяются до максимально возможной скорости (то есть 1000 Мбит/с), даже если оно не способно на это.
Так как же драйвер phy обрабатывает такую ситуацию? Нормально ли, что link меняет свою конфигурацию таким образом, если происходит такая аппаратная ошибка? Изменение размера чтения с int на u16 может решить проблему, так почему же этого не сделать?
Все эти проблемы наблюдались в ядре Linux 3.8.13. Последний исходный код Linux, похоже, похож, хотя я не тестировал ситуацию с ошибкой в нем.