k000858 0 18 мая, 2018 Опубликовано 18 мая, 2018 · Жалоба Портирую драйвер сетевого устройства (в общем ethernet драйвер) в OpenWRT. Драйвер успешно создает сетевой интерфейс и тд ондако ничего не работает. Не тикают даже счетчики в статистике. Сам драйвер выдран из SDK с 3.10.* ядром, в OpenWRT 4.4.14 ядро Пока удалось выяснить что по каким то причинам не производится полинг интерфейса. Сам интерфейс создается с помощью netif_napi_add, в аргументах которой указывается полинг функция. (которая, как выяснилось почему то не вызывается) Кто сталкивался с подобным эффектом, или может у кого есть идейки куда капнУть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winniethepooh 0 18 мая, 2018 Опубликовано 18 мая, 2018 (изменено) · Жалоба Портирую драйвер сетевого устройства (в общем ethernet драйвер) в OpenWRT. Драйвер успешно создает сетевой интерфейс и тд ондако ничего не работает. Не тикают даже счетчики в статистике. Сам драйвер выдран из SDK с 3.10.* ядром, в OpenWRT 4.4.14 ядро Пока удалось выяснить что по каким то причинам не производится полинг интерфейса. Сам интерфейс создается с помощью netif_napi_add, в аргументах которой указывается полинг функция. (которая, как выяснилось почему то не вызывается) Кто сталкивался с подобным эффектом, или может у кого есть идейки куда капнУть? я вообще не специалист по сетевому стеку, но насколько я понимаю сетевое устройство дергает хардверным прерыванием далее начинает работать драйвер сетевого ус-ва и для начала я бы посмотрел обрабатываются ли прерывания и что на входе у драйвера. Полинг (если я не ошибаюсь запускают софтверные прерывания когда в кольцевом буфере появляются данные от сетевого устройства). Вставить в код printf там где вызываются обработчики. Простите если не въехал в "тему" я просто пытаюсь сказать как бы я действовал на вашем месте. Изменено 18 мая, 2018 пользователем winniethepooh Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 21 мая, 2018 Опубликовано 21 мая, 2018 · Жалоба я вообще не специалист по сетевому стеку, но насколько я понимаю сетевое устройство дергает хардверным прерыванием далее начинает работать драйвер сетевого ус-ва и для начала я бы посмотрел обрабатываются ли прерывания и что на входе у драйвера. Полинг (если я не ошибаюсь запускают софтверные прерывания когда в кольцевом буфере появляются данные от сетевого устройства). Вставить в код printf там где вызываются обработчики. Простите если не въехал в "тему" я просто пытаюсь сказать как бы я действовал на вашем месте. Вы все верно описали - мой драйвер работает по NAPI модели: 1. Драйвер включает NAPI, но изначально тот находится в неактивном состоянии. 2. Прибывает пакет, и сетевая карта напрямую отправляет его в память. 3. Сетевая карта генерирует IRQ посредством запуска обработчика прерываний в драйвере. 4. Драйвер будит подсистему NAPI с помощью SoftIRQ (подробнее об этом — ниже). Та начинает собирать пакеты, вызывая в отдельном треде исполнения (thread of execution) зарегистрированную драйвером функцию poll. 5. Драйвер должен отключить последующие генерирования прерываний сетевой картой. Это нужно для того, чтобы позволить подсистеме NAPI обрабатывать пакеты без помех со стороны устройства. 6. Когда вся работа выполнена, подсистема NAPI отключается, а генерирование прерываний устройством включается снова. 7. Цикл повторяется, начиная с пункта 2. Прерываний нет (не только по прибытию входящих пакетов но и на изменение линка). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winniethepooh 0 21 мая, 2018 Опубликовано 21 мая, 2018 · Жалоба Вы все верно описали - мой драйвер работает по NAPI модели: 1. Драйвер включает NAPI, но изначально тот находится в неактивном состоянии. 2. Прибывает пакет, и сетевая карта напрямую отправляет его в память. 3. Сетевая карта генерирует IRQ посредством запуска обработчика прерываний в драйвере. 4. Драйвер будит подсистему NAPI с помощью SoftIRQ (подробнее об этом — ниже). Та начинает собирать пакеты, вызывая в отдельном треде исполнения (thread of execution) зарегистрированную драйвером функцию poll. 5. Драйвер должен отключить последующие генерирования прерываний сетевой картой. Это нужно для того, чтобы позволить подсистеме NAPI обрабатывать пакеты без помех со стороны устройства. 6. Когда вся работа выполнена, подсистема NAPI отключается, а генерирование прерываний устройством включается снова. 7. Цикл повторяется, начиная с пункта 2. Прерываний нет (не только по прибытию входящих пакетов но и на изменение линка). непроинициализировано (неправвильно или неисправно) сетевое устройство, как бы самое простое предположение.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 21 мая, 2018 Опубликовано 21 мая, 2018 · Жалоба непроинициализировано (неправвильно или неисправно) сетевое устройство, как бы самое простое предположение.. что могло так смениться в версиях ядра? сам драйвер прекрасно работает в 3.10.* все подозрения на неработающее прерывание (нет реакции на изменение линка) в начале работы драйвер даже не компилировался, например изза отсутствия в ядре IRQF_DISABLED (удален с 4.12.5 ядра). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winniethepooh 0 21 мая, 2018 Опубликовано 21 мая, 2018 (изменено) · Жалоба что могло так смениться в версиях ядра? сам драйвер прекрасно работает в 3.10.* все подозрения на неработающее прерывание (нет реакции на изменение линка) в начале работы драйвер даже не компилировался, например изза отсутствия в ядре IRQF_DISABLED (удален с 4.12.5 ядра). почему старый драйвер не хочет работать с другим ядром я не могу предположить, но есть вероятно другие драйвера для нового ядра и можно посмотреть в чем отличия..,(изменился номер прерывания, не так регистрируется обработчик, не конфликтует ли с другим устройством т.к. общее прерывание) кажется была у linux возможность посмотреть на каких устройствах какие номера обработчиков зарегистрированы.. Изменено 21 мая, 2018 пользователем winniethepooh Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 21 мая, 2018 Опубликовано 21 мая, 2018 · Жалоба почему старый драйвер не хочет работать с другим ядром я не могу предположить, но есть вероятно другие драйвера для нового ядра и можно посмотреть в чем отличия..,(изменился номер прерывания, не так регистрируется обработчик, не конфликтует ли с другим устройством т.к. общее прерывание) кажется была у linux возможность посмотреть на каких устройствах какие номера обработчиков зарегистрированы.. сравниваю интегрируемый драйвер с имеющимися под новое ядро: - в старом интегрируемом драйвере номер прерывания задан дифайном #define IRQ_ENET0 3 /* hardware interrupt #3, defined in ... - в новом драйвере номер прерывания выбирается вызовом функции platform_get_irq может тут какое то несоответствие? мне этот момент не очень понятен.. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sadmix 0 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба - в новом драйвере номер прерывания выбирается вызовом функции platform_get_irq может тут какое то несоответствие? мне этот момент не очень понятен.. А как ваше интегрируемое сетевое устройство описано в Device tree? Как там сейчас задается прерывание? кажется была у linux возможность посмотреть на каких устройствах какие номера обработчиков зарегистрированы.. cat /proc/interrupts ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winniethepooh 0 22 мая, 2018 Опубликовано 22 мая, 2018 (изменено) · Жалоба cat /proc/interrupts ? да оно Изменено 22 мая, 2018 пользователем winniethepooh Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба А как ваше интегрируемое сетевое устройство описано в Device tree? Как там сейчас задается прерывание? cat /proc/interrupts ? Вроде как никак не описано. Сам драйвер вызывается module_init(ra2882eth_init); module_exit(ra2882eth_cleanup_module); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sadmix 0 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Вроде как никак не описано. Сам драйвер вызывается module_init(ra2882eth_init); module_exit(ra2882eth_cleanup_module); Тогда выложите куда-нибудь посмотреть вашу ф-цию probe() из драйвера интегрируемого сетевого устройства (т.е. ф-цию инициализации драйвера). Если есть подозрения на нерабочие прерывания, нужно посмотреть как они задаются на этапе инициализации - printk куда-нибудь поставить... (если я конечно правильно понимаю проблему) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Тогда выложите куда-нибудь посмотреть вашу ф-цию probe() из драйвера интегрируемого сетевого устройства (т.е. ф-цию инициализации драйвера). Если есть подозрения на нерабочие прерывания, нужно посмотреть как они задаются на этапе инициализации - printk куда-нибудь поставить... (если я конечно правильно понимаю проблему) Проблема с прерываниями уже решена. Что сделал: - подсмотрел номера нужных мне прерываний через cat /proc/interrupts в ОС при работающем родном драйвере openWRT (который я пытаюсь заменить на интегрируемый). - заменил номера прерываний на подсмотренные в дефайнах интегрируемого драйвера Родной openwrt инициализируется через module_platform_driver, номера прерываний задаются в device tree и передаются в драйвер через MODULE_DEVICE_TABLE (если я все верно понимаю). В интегрируемом мной драйвере же номера прерываний заданы в дефайнах. Почему они отличаются..не понимаю. К слову, мое сетевое устройство это встроенный в SoC свитч, MT7621 SoC. Прерывания на изменение линка и получение данных заработали. Так же заработала поллинг-функция. Дальше пакеты (в ОС) почему то не поступают, разбираюсь дальше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sadmix 0 22 мая, 2018 Опубликовано 22 мая, 2018 · Жалоба Дальше пакеты (в ОС) почему то не поступают, разбираюсь дальше. А как они поступают в ОС, в драйвере нужно вызвать netif_rx(skb) кажется? Кстати, что у вас возвращает ф-ция netif_rx? Я с NAPI моделью не работал, но думаю, что логика должна быть похожа: При возникновении rx прерывания создаем skb из принятых данных: skb = netdev_alloc_skb(net_dev, len); и далее что-то типа этого: data = skb_put(skb, len); memcpy_fromio(data, addr, len); netif_rx(skb); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k000858 0 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба А как они поступают в ОС, в драйвере нужно вызвать netif_rx(skb) кажется? Кстати, что у вас возвращает ф-ция netif_rx? Я с NAPI моделью не работал, но думаю, что логика должна быть похожа: При возникновении rx прерывания создаем skb из принятых данных: skb = netdev_alloc_skb(net_dev, len); и далее что-то типа этого: data = skb_put(skb, len); memcpy_fromio(data, addr, len); netif_rx(skb); да, что то вроде того. все верно описали вы. в моем случае почему то не доходит до netif_rx, в драйвере куча ветвлений логики и препроцессора (#if) разбираюсь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
winniethepooh 0 23 мая, 2018 Опубликовано 23 мая, 2018 · Жалоба да, что то вроде того. все верно описали вы. в моем случае почему то не доходит до netif_rx, в драйвере куча ветвлений логики и препроцессора (#if) разбираюсь. В DMA входящие пакеты складывает? drop для пакетов не происходит? должна быть функция опроса типа RXDESC receive (RECEIVE DESCRIPTOR) читающая статусы имеющихся дескрипторов пакетов на предмет передачи их наверх (netif_rx) есть выходные данные у этой функции? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться