LINUX.ORG.RU

Wireless драйвер: ioctl SIOCGIWNAME

 ,


0

2

Имеется wifi чип, драйвер под openwrt (4.14.*). Драйвер исправно работает (wifi так же работает хорошо), однако не могу до драйвера не могу достучаться через ioctl - при попытке не происходит вызова .ndo_do_ioctl колбэка. Достучаться в основном пытаюсь с помощью команды SIOCGIWNAME (да и многими другими, которые в драйвере описаны), однако например 0x8947 команда колбэк все же вызывает.

От чего это зависит? как заставить драйвер работать с любыми командами (повторюсь, нужно что бы хотя обработчик срабатывал, сами команды уже описаны в обработчике)

есть подозрение, что для работы этих команд необходимо драйвером идентифицировать чип как Wireless, возможно помещением инфы в /proc/net/wireless (в /proc/net/dev инфа есть)

Как заставить драйвер это делать?

k000858
() автор топика
Ответ на: комментарий от k000858

Хммм... На уровне предположений.

Вообще-то, для начала, хотелось бы посмотреть на код этого самого драйвера.

В wifi модуле, условно говоря, есть две стороны. Первая, которая у Вас реализована, т.к. данные шлются, это сторона обмена данными. Вторая, которая реализована либо криво, либо не полностью, это сторона управления. Сторона управления реализуется через netlink и описана в nl80211.h.

Вот в стороне управления всё интереснее может быть. Там может быть либо full MAC, либо soft MAC. Понимание какое именно устройство определяет то, как с ним работать.

Full MAC регистрирует свои операции в cfg80211, который по уровню сразу под ним, через структуру cfg80211_ops. Пример использования данной структуры Вы можете найти в /usr/src/linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c, строка 5144. Очевидно, что Вам надо сделать по аналогии, если у Вас full MAC-устройство. Т.е., Вам надо проверить функции управления.

В случае soft MAC Вам нужно учитывать что работа строится через слой, предоставляемый ядром. Это mac80211. В этом случае модуль регистрируется через слой mac80211 посредством описания своих функций в структуре ieee80211_ops. Как пример /usr/src/linux/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c, стр. 4406.

Т.е., в обоих случаях, надо начинать разматывать клубочек либо с одной структуры, либо с другой, в зависимости от вида устройства. Что-то из функций, похоже, у Вас как-то криво реализовано, либо не реализовано вовсе. Это, я подчеркну, не видя кода, чисто навскидку что можно сказать. Ну а как там оно в реале я отсюда не вижу. =)

И да, посмотрите https://wireless.wiki.kernel.org/_media/en/developers/documentation/mac80211.pdf Хорошо всё расписано.

Moisha_Liberman ★★
()
Ответ на: Хммм... На уровне предположений. от Moisha_Liberman

Кстати. Пока не забыл.

Вот ещё https://www.linkedin.com/pulse/wlan-drivers-code-walk-linux-bhanu-prakash-singh Прямо с картинками, для наглядности.

Так же https://www.linux.com/blog/linux-wireless-networking-short-walk

Вот совсем наглядно, в т.ч. и про то, что за устройства с full MAC и soft MAC вот тут у индийской женщины https://www.slideshare.net/DherytaJaisinghani/tutorial-wifi-driver-code-openi...

И, само собой, https://wireless.wiki.kernel.org/en/developers/documentation

Moisha_Liberman ★★
()
Ответ на: Хммм... На уровне предположений. от Moisha_Liberman

mac80211 в драйвере не реализован. в драйвере используется устаревший метод управления через ioctl, причем все работает в SDK с более старым ядром, но не работает в openWrt с 4.14.*

k000858
() автор топика
Ответ на: комментарий от k000858

А, блин! Понял!

Мне нужно было сразу сказать что дело тут весьма тухло выглядит. Т.е., если по-хорошему, то лучше бы модуль привести в соответствие с тем, как положено писать модули именно для Wi-Fi. У Вас модуль написан как «обще-ethernet device». Так можно, но это уже плохая практика. Рано или поздно, но найдёте себе проблем, впрочем, уже как я понимаю. Нашли. Ладно, Бог с ним.

Короче.

возможно помещением инфы в /proc/net/wireless (в /proc/net/dev инфа есть) Как заставить драйвер это делать?

Смотрим описалово https://elixir.bootlin.com/linux/latest/source/net/wireless/wext-proc.c

/*

* The /proc/net/wireless file is a human readable user-space interface * exporting various wireless specific statistics from the wireless devices. * This is the most popular part of the Wireless Extensions ;-) * * This interface is a pure clone of /proc/net/dev (in net/core/dev.c). * The content of the file is basically the content of «struct iw_statistics». */

Т.е., если у Вас есть инфа в /proc/net/dev, то получается что ядро не зарегистрировало модуль именно как модуль Wi-Fi (wi-fi extension). Тогда Вам следует в инициализации своего устройства использовать ф-ю https://elixir.bootlin.com/linux/latest/source/net/wireless/wext-proc.c#L129 wext_proc_init(), она делает эту работу.

при попытке не происходит вызова .ndo_do_ioctl колбэка

int (*ndo_do_ioctl)(struct net_device *dev, 		        struct ifreq *ifr, int cmd);

Когда команда распознаётся ядром, вызывается соответствующий коллбэк (dev->ndo_do_ioctl), релевантный Вашему модулю. Здесь третий аргумент это Ваша команда, второй аргумент это указатель на адрес в kernel space, содержащий копию структуры, передаваемую из user space. Специфичные для устройства команды выбираются из соответствующих полей в struct ifreq *. Они стандартизированы и сюрпризов здесь по идее быть не должно.

Чисто примера ради как люди работают с данной функцией, вот из дерева dd-wrt пример. https://svn.dd-wrt.com/browser/src/linux/universal/linux-3.4/drivers/staging/...

Возможно, что Вы правы. Т.е., для начала зарегистрируйте модуль как wi-fi ext., посмотрите что туда прилетает и, если обработчики в коллбэке реализованы, то всё должно заработать. Но так-то лучше бы переползать помаленьку на нормальную архитектуру модуля, чисто для Wi-Fi.

Извините что так подробно, я просто стараюсь максимально чётко объяснить что к чему, т.к. не знаю каков experience моего собеседника. Извините если что не так.

А так-то, если совсем уж по-хорошему, то исходя из:

причем все работает в SDK с более старым ядром

Пнуть бы авторов этого самого SDK. И модуль по-нормальному сделать прежде всего.

Moisha_Liberman ★★
()
Ответ на: А, блин! Понял! от Moisha_Liberman

Премного благодарен за столь подробное описание!

В ближайшее время попробую применить к драйверу wext_proc_init()

ЗЫ: драйвер Mediatek (ака Ralink когда то)

k000858
() автор топика
Ответ на: комментарий от k000858

Ещё раз извините.

Просто, начальная информация была весьма скудна. Например, что там за SDK? Если реалдык (Realtek), то можно было бы что-нибудь более конкретно. В принципе, после весьма тесного общения с этим... SDK, я могу сказать что я в жизни видел всё. Вот вообще всё. Даже индусский код уже не пугает после китайского. =)))

Ralink? Ясно. =) Сейчас вот палочкой тыкаю в banana pi bpi r2. Это которая типа роутер с 2Gb RAM, 2 SATA drives, это вот эта вот https://bananapi.gitbooks.io/banana-pi-bpi-r2-open-source-smart-router/conten...

Как раз с OpenWRT/LEDE развлекаюсь. Там есть инструкция по сборке, собрал для SD-card, eMMC не хочу пока трогать. И там как раз Ralink. =) Вот тут http://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:wlan мужик со всяким-разным для Ralink под banana pi bpi r2 колупался, можно в его репах посмотреть, если что, структура модулей хоть и для разных чипов, но будет похожа.

Правда, сейчас дотыкаю (забыл изначально некоторые вещи посмотреть в LEDE) и заново туда пересоберу генточку. Ибо хочу я полу-роутер, полу-сервер (с nginx, своим софтом, блекджеком и шлюхами, пардон, бриджем и поэтессами). Ну и так, имея 2 SATA, глупо было бы их в RAID не собрать, хоть софтовый. И transmission с remote control туда. Хоть и порочный это путь, оно бы лучше роутер отдельно, а сервер отдельно, но для домашнего использования почему бы и нет.

А так-то, если что, то спрашивайте, чем смогу помочь, тем помогу. «Люблю» я странною любовью эти ваши китайские SDK... =)))

Moisha_Liberman ★★
()
Ответ на: Ещё раз извините. от Moisha_Liberman

Пересмотрел код: wext_proc_init() вызывается, но не драйвером а ядром - вызов происходит из ядерной dev_proc_net_init, которая в свою очередь вызывается в net_dev_init при старте системы (еще до инициализаций драйверов).

добился сбора инфы по моему интерфейсу (ra0) в /proc/net/wireless (достаточно было разрешить один дифайн и драйвер сам проинициализировал нужное - iw функции).

итог: - iwpriv работает - показывает список доступных IOCTL команд для интерфейса - iwinfo не работает - внутри него не работает вызываемая iotcl функция с командой SIOCGIWNAME. - ни одна команда ioctl, связанная с Wireless не вызывает ioctl колбэк в драйвере кроме пары команд, взятых из езернета.

ват э фак?

k000858
() автор топика
Ответ на: комментарий от k000858

В общем решение: вероятно в новом ядре Wireless команды ioctl не доступны по стандартного колбэку .ndo_do_ioctl. Для их обработки необходимо инициализировать wireless_handlers (это поле в net_device структуре). Стандартные Wireless команды доступны по .standard колбеку wireless_handlers структуры.

k000858
() автор топика
Ответ на: комментарий от k000858

Да.

вызов происходит из ядерной dev_proc_net_init, которая в свою очередь вызывается в net_dev_init при старте системы (еще до инициализаций драйверов).

Ну... да, а потом драйвер просто подключается к проинициализированной ядерной структуре, добавляя к ней свои обработчики.

добился сбора инфы по моему интерфейсу (ra0) в /proc/net/wireless (достаточно было разрешить один дифайн и драйвер сам проинициализировал нужное - iw функции).

Это хорошо, но боюсь, этого мало будет. Именно потому, что драйвер, несмотря на то, что для wireless чипа, написан как для common ethernet device.

Именно поэтому:

ни одна команда ioctl, связанная с Wireless не вызывает ioctl колбэк в драйвере кроме пары команд, взятых из езернета.

Т.е., если мы делаем ifconfig up или down, то коллбэки, ответственные за включение/отключения модуля срабатывают, а вот что-то специфичное для wi-fi мимо пролетит. Именно этого я и опасался, когда сказал что:

У Вас модуль написан как «обще-ethernet device».

Moisha_Liberman ★★
()
Ответ на: комментарий от k000858

Нет.

а есть способ не инициализировать вручную а заставить ловить стандартный колбэк по ioctl?

В данном случае нет. Просто потому, что драйвер ничего не знает о тех структурах ядра, которые он должен использовать в этом случае. Сейчас он знает что он ethernet-device. Сделали ifconfig интерфейс up, заработало. Сделали ifconfig интерфейс down — перестало работать. А то, что это на самом деле soft MAC или full MAC, драйверу сугубо по барабану. У него внутри нет структур, которые нужны для колбэков в таком случае. Т.е., может работать, но скорее всего не повезло. Что, к стати, мы и видим. Данные через этот интерфейс-то бегают же? Бегают. Но он практически неуправляем. Для извращённой логики в OpenWRT, когда там линукс конечно, но такой... для роутеров, всего бы поменьше, утиля там, ещё чего, этого хватает. Для полнофункциональной работы скорее всего этого хватать не будет, но это

Я тут порылся, нашёл https://github.com/dt99/mt7615 Похоже на утечку из официального SDK, который распространяется под NDA. Если Вы вспомните, то выше я писал что для того, чтобы эта байда работала по-нормальному, надо менять структуру драйвера и реализовывать всё, что необходимо, по-взрослому.

О чём и речь. Вон, смотрите, https://github.com/dt99/mt7615/tree/master/mt_wifi/os/linux, в самом верху там каталог cfg80211. Т.е., это, по идее, устройство Full MAC. Которое использует https://www.kernel.org/doc/html/v4.12/driver-api/80211/cfg80211.html Теперь остаётся «только» запортировать всё это добро в дерево исходников OpenWRT.

Да, вместе со слоем сfg80211 от Mediatek. Смотрите на config.mk.cfg80211. Вроде и поддержка wpa_supplicant там есть.

Так же посмотрите чтобы на месте были бы прошивки (.bin) для устройства. Без них девайс не заведётся.

Ну и теперь сравните что есть у Вас и что вон, в github выложено. Вот Вам и разница между тем, что есть и тем, что нужно чтоб было. =)

Moisha_Liberman ★★
()
Ответ на: Нет. от Moisha_Liberman

Используется именно драйвер из SDK, я уже писал выше.

Не хочется спорить но mac80211 (cfg80211 + netlink api) это просто более современный метод управления драйвером (Wireless девайсом), ioctl (альтернатива) - устаревший метод, но имеющий право на жизнь = вполне рабочий вариант.

По 80211: в данном драйвере опять же древняя реализация не стыкующаяся с современным апи в опенВрт. Пилить и пилить...что б взлетело. Куда быстрее завести альтернативный метод ioctl. В принципе уже работает. Смутило просто почему Wireless команды не проходят по стандартному колбэку, но ответ вероятно в том, что такое прокатывало в старой версии ведра, а в новой необходимо иниицализировать на каждую команду свой колбэк через wireless_handlers. В принципе это уже работает. Но хотелось бы увидеть подтверждение или опровержение этого факт. Во втором случае хотелось бы понять что сделать что бы Wireless команды проходили по стандартному колбэку. 80211 не предлагать - это альтернатива, она работает не через ioctl

k000858
() автор топика
Ответ на: комментарий от k000858

Ну тогда альтернатив несколько.

1. Оставить как есть. SDK не Ваш, портировать по-нормальному это долго и дорого и нудно, если честно, в то же время железка как-то, да работает. А на OpenWRT делать, например, опрос всех соседних SSID с целью построить карту Wi-Fi сетей в округе... Я не видел чего-то желающих. Ну или что-то аналогичное. Как правило, работает, трафик качает, да и ладно. Для «побаловаться вардрайвингом» есть другие средства и системы.

2. Остаться на более старом ядре. Правда, можно глянуть что в сборке для 4.14 поменялось по сравнению с предыдущими вариантами, т.к. это несколько странно чтобы вот так, без объявления войны API резко поменяли. Возможно что что-то там в 4.14 у Вас недособралось. Или дефайны стоят. Внезапно. Попробовать пересобрать как было раньше, но тут тоже вопросы. Может, поможет, может нет. Я бы на это не расчитывал.

3. Портировать по-взрослому. Ну, если за отдельные деньги, то почему бы и нет? Тогда надо брать SDK и колупать в деталях что там и к чему. Но я бы не полез, если честно, т.к. в следующей версии SDK неизвестно что в голову китайским коллегам стрельнёт. Они и сами могут очнуться. И тогда вся работа псу под хвост.

Смутило просто почему Wireless команды не проходят по стандартному колбэку, но ответ вероятно в том, что такое прокатывало в старой версии ведра, а в новой необходимо иниицализировать на каждую команду свой колбэк через wireless_handlers. В принципе это уже работает. Но хотелось бы увидеть подтверждение или опровержение этого факт. Во втором случае хотелось бы понять что сделать что бы Wireless команды проходили по стандартному колбэку.

Потому что для wireless это не стандартный колбэк. Для wireless стандартно это либо Full, либо Soft MAC. И, как следствие, это wireless handlers. У Вас используются колбэки для ethernet device. В общем и целом. Про wireless драйвер ни чего не знает несмотря на то, что там «что-то» реализовано. Со структурами ядра-то структуры драйвера не взаимодействуют! Значит, и реализации нет. То что не работает путём, того нет. =)

По 80211: в данном драйвере опять же древняя реализация не стыкующаяся с современным апи в опенВрт.

Ага. Я уже глянул. Правда, у меня нет платы и чипа, но уже поглядел на код. Да, я про то и говорю. Если по-взрослому, то надо приводить в соответствие код модуля коду ядра. Но тут вопрос а не ну ли его на хер? Или за какие деньги эти развлечения? Тут перепахивать... считай всё. WRT или не WRT, особой разницы нет. По крайней мере, она не фатальна. Но трудозатраты здесь в любом случае будут очень большие.

Смысла не вижу. Разве что потом продать этот модуль китайцам взад =))) , но врядли они купят.

Moisha_Liberman ★★
()
Ответ на: комментарий от k000858

UPD. Добавлю.

На глаза попалось просто, решил добавить.

Взято из http://forum.banana-pi.org/t/bpi-r2-with-bpi-7615-based-on-mt7615-module-deve...

Там чуваки платку на mtk 7615 с pci-e сгондобили, фоточка там есть. Но дело не в этом. Прикол в комменте ниже (в начале человек написал что он портирует модуль с 4.16 на 4.14, что вызвало закономерное удивление и он поправился):

I made a mistake, Vendor just supports kernel 4.4, don’t have plan to support V4.16 yet. Of couce the V4.14 is working for R2, but lots of functions are not implemented yet.

Чем-то напомнило Вашу ситуацию. В общем, смело оставляйте ASIS. Все остальные вопросы к вендору. Он за это свои бабки получает.

Moisha_Liberman ★★
()
Ответ на: UPD. Добавлю. от Moisha_Liberman

та в общем у меня уже все работает под 4.14.* (портировано с 3.10.*). проблем пока не вылезало никаких...пока.

странно конечно что с ioctl так сходу решение не нагуглилось (мол «в новых ядрах ля ля ля ..).

k000858
() автор топика
Ответ на: комментарий от k000858

Работает и хорошо.

А про новые вёдра ни кто особо не упирается рассказывать, так оно тоже понятно почему. В большинстве случаев основной массе пользюков оно лет 300 подряд не нужно что там и к чему. Те, кому оно всё вот это вот надо, те в курсе что структура модуля для net device и для wireless device, она малость разная, хотя, wireless device это отдельный и особый случай net device. И, в принципе, можно (с некоторыми допущениями) и так и этак. Но net device сам по себе проще. Так что, разрабы SDK сделали хоть как-то и тоже хорошо. Лишь бы трафик качало.

Вон, даже сами разработчики SDK не особо разбегаются портировать по-нормальному. Чёттам как-то там работает и слава Богу. Да и чип, если честно, не особо распространённый. Когда все выше перечисленные факторы складываются в кучку, то имеем то, что имеем.

В общем, для себя чисто так картинка с MT7615 понятна.

Moisha_Liberman ★★
()
17 декабря 2018 г.
Ответ на: комментарий от k000858

подскажите пожалуйста какой дефайн нужно разрешить чтоб iwpriv c mtk-шным драйвером заработал ?

leks
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.