Дружим RaspberryPi с TP-Link TL-WN727N

Привет, Хабр!

Задумал как-то я подключить свою малинку к интернету по воздуху.

Сказано-сделано, для этого был приобретен в ближайшем магазине usb wi-fi свисток небезызвестной фирмы TP-Link. Сразу скажу, что это не какой-то там нано usb модуль, а вполне себе габаритный девайс размером примерно с обычную флешку(ну или если вам будет угодно с указательный палец взрослого мужчины). Перед покупкой я немного изучил список поддерживаемых производителей свистков для RPI и TP-Link в списке был(правда как потом оказалось я не учел тонкостей, ведь дьявол как известно кроется в деталях). Итак, хладный сказ о моих злоключениях начинается, вашему вниманию предлагается детективная история в 3-х частях. Заинтересованных прошу под кат.

Статья Подключаем WiFi-адаптер WN727N к Ubuntu/Mint мне частично помогла, но обо всем по порядку.

Условия задачи

Дано:

  1. одноплатный компьютер Raspberry Pi 2 B v1.1 — 1 штука
  2. usb wi-fi свисток WN727N — 1 штука
  3. пара не совсем кривых рук — 2 штуки
  4. в качестве ос установлен последний Raspbian (на основе debian 10 Buster)
  5. ядро версии 4.19.73-v7+

Найти: осуществить подключение к интернету(вайфай раздается от домашнего роутера)

После распаковки адаптера читаю инструкцию внутри:

System Compatibility: Windows 10/8/7/XP (даже небо, даже ХР) and MacOS 10.9-10.13

Мда, о линуксах как обычно ни слова. Шел 2к19, а драйвера было нужно все еще собирать вручную…

У нас было с собой 2 компилятора, 75 тысяч библиотек, пять бинарных блобов, полмассива голых баб с логотипом и целое море хедеров всех языков и разметок. Не то, чтобы это был необходимый набор для работы. Но если начал собирать систему под себя, становится трудно остановиться. Единственное, что вызывало у меня опасения — это драйвера под wi-fi. Нет ничего более беспомощного, безответственного и испорченного, чем сборка драйверов из исходников. Но я знал, что рано или поздно мы перейдем и на эту дрянь.

Вообще как известно возня с usb wi-fi на линуксе это больно и несколько невкусно (как русские суши).

В коробке лежит еще CD-диск с драйверами. Без особой надежды смотрю что на нем есть — точно, не позаботились. Поиск в интернете вывел меня на сайт производителя, но там есть линукс драйвер только для ревизии устройства v4, а у меня на руках была v5.21. И к тому же под очень старые версии ядра 2.6-3.16. Обескураженый неудачей уже в самом начале я уж подумал, что надо было брать TL-WN727N (он чуток подороже и умеет в 300Mbps против 150 у моего, но это как оказалось для малинки вообще значения не имеет, об этом будет написано далее). Но и самое главное драйвера под него уже есть и ставятся просто пакетом firmware-ralink. Посмотреть ревизию устройства обычно можно на корпусе устройства на наклейке рядом с серийным номером.

Дальнейшее гугление и посещение разных форумов особо ничего хорошего не принесло. Видимо никто до меня такой именно адаптер подключать на линукс не пробовал. Мда, везет мне как утопленнику.

Хотя нет, вру, посещение форумов(в основном англоязычных) тоже дало свои плоды, в некоторых топиках мелькало упоминание некого господина lwfinger, который славится тем, что написал некоторое количество драйверов для вайфай адаптеров. Его гит репозиторий в конце статьи в ссылках. И второй урок какой я усвоил — нужно идентифицировать свое устройство, чтобы понять какой драйвер для него может подойти.

Часть 1. Идентификация Борна

При включении устройства в порт никакой светодиод конечно не загорелся. И вообще никаким образом не понятно работает что-то или нет.

Первым делом для выяснения видит ли ядро наш девайс заглядываю в dmesg:

[  965.606998] usb 1-1.3: new high-speed USB device number 9 using dwc_otg
[  965.738195] usb 1-1.3: New USB device found, idVendor=2357, idProduct=0111, bcdDevice= 0.00
[  965.738219] usb 1-1.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  965.738231] usb 1-1.3: Product: 802.11n NIC
[  965.738243] usb 1-1.3: Manufacturer: Realtek
[  965.738255] usb 1-1.3: SerialNumber: 00E04C0001

Оказалось видит, и даже понятно что там чип Realtek и сам VID/PID устройства на шине usb.

Идем дальше, смотрим lsusb, и тут нас поджидает очередная неудача

Bus 001 Device 008: ID 2357:0111 
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp. SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Система не знает что это за девайс, и стыдливо показывает пустое место вместо имени(хотя vendor=2357 это точно TP-Link).

На этом этапе пытливый читатель наверно уже заметил кое-что занимательное, но мы отложим это до своего времени.

Исследование проблемы пустых имен вывело меня на сайт с идентификаторами, куда заносится информация по известным VID/PID. Нашего 2357:0111 там не оказалось. Как выяснилось позднее, утилита lsusb использует файл /usr/share/misc/usb.ids, который является тем же списком идентификаторов с этого сайта. Для красоты отображения я просто добавил у себя в системе в него строки для вендора TP-Link.

2357  TP-Link
        0111  TL-WN727N v5.21

Ну отображение в списке устройств то мы поправили, а к выбору драйвера это нас особо не приблизило ни на шаг. Для выбора драйвера нужно знать на каком чипе сделан ваш свисток. Очередные безуспешные попытки узнать это в интернете ни к чему хорошему не привели. Вооружившись тонкой шлицевой отверткой аккуратно поддеваю крышечку адаптера и моему взору предстает во всей своей первозданной наготе порочное детище дяди Ляо. Под лупой можно рассмотреть наименование чипа — RTL8188EUS. Это уже хорошо. На каких-то форумах я видел посты, что под этот чип хорошо подходит как раз драйвер того самого господина lwfinger(даже несмотря на то что у него написано только про RTL8188EU).

Часть 2. Превосходство Борна

Качаю исходники драйвера из гита.

Настало время переустановить шиндоус заняться тем, с чем обычно связывают линуксоидов — сборкой чего-то из сорцов. Сборка драйверов как оказалось мало отличается от компиляции программ:

make
sudo make install

но для компиляции модулей ядра нам нужны заголовочные файлы ядра для нашей конкретной версии.

В стоковом репозитории есть пакет raspberrypi-kernel-headers, но он содержит версию файлов для ядра 4.19.66-v7l+, и это нам не подходит. Но для получения заголовков нужной версии как выяснилось есть удобная тулза rpi-source (ссылка в конце на гитхабе), с помощью которой можно скачать нужные заголовки. Клонируем репозиторий, делаем скрипт исполняемым, запускаем. Первый запуск валится с ошибкой — нет утилиты bc. К счастью она есть в репозитории и мы ее просто устанавливаем.

sudo apt-get install bc

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

После того как все заголовки скачались, проверяем что появился каталог /lib/modules/4.19.73-v7+ и в нем симлинк указывает на то место, где лежат скачаные файлы(у меня это /home/pi/linux):

pi@raspberrypi:/home/pi/rtl8188eu# ls -l /lib/modules/4.19.73-v7+/
lrwxrwxrwx  1 root root     14 Sep 24 22:44 build -> /home/pi/linux

Подготовительный этап пройден, можно приступать к сборке. Сборка модулей занимает опять определенное время, малинка зверь не быстрый(камень у нее 32bit 900Mhz Cortex ARM v7).
Итак, все скомпилировалось. Инсталлируем драйвер 2м шагом (make install), при этом же происходит копирование еще файлов firmware, необходимых для работы драйвера:

install:
        install -p -m 644 8188eu.ko  $(MODDESTDIR)
        @if [ -a /lib/modules/$(KVER)/kernel/drivers/staging/rtl8188eu/r8188eu.ko ] ; then modprobe -r r8188eu; fi;
        @echo "blacklist r8188eu" > /etc/modprobe.d/50-8188eu.conf
        cp rtl8188eufw.bin /lib/firmware/.
        /sbin/depmod -a ${KVER}
        mkdir -p /lib/firmware/rtlwifi
        cp rtl8188eufw.bin /lib/firmware/rtlwifi/.

Часть 3. Ультиматум Борна

Втыкаю свисток в порт и… ничего не происходит. Это что все было впустую?

Начинаю изучать файлы внутри проекта и в одном из них нахожу то, в чем была проблема: у драйвера указывается полный список идентификаторов VID/PID, которые он может обслужить. И для того чтобы наше устройство с этим драйвером работало я просто добавил свой id в файл rtl8188eu/os_dep/usb_intf.c

static struct usb_device_id rtw_usb_id_tbl[] = {
        /*=== Realtek demoboard ===*/
        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)}, /* 8188EUS */
        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)}, /* 8188ETV */
        /*=== Customer ID ===*/
        /****** 8188EUS ********/
        {USB_DEVICE(0x07B8, 0x8179)}, /* Abocom - Abocom */
        {USB_DEVICE(0x0DF6, 0x0076)}, /* Sitecom N150 v2 */
        {USB_DEVICE(0x2001, 0x330F)}, /* DLink DWA-125 REV D1 */
        {USB_DEVICE(0x2001, 0x3310)}, /* Dlink DWA-123 REV D1 */
        {USB_DEVICE(0x2001, 0x3311)}, /* DLink GO-USB-N150 REV B1 */
        {USB_DEVICE(0x2001, 0x331B)}, /* D-Link DWA-121 rev B1 */
        {USB_DEVICE(0x056E, 0x4008)}, /* Elecom WDC-150SU2M */
        {USB_DEVICE(0x2357, 0x010c)}, /* TP-Link TL-WN722N v2 */
        {USB_DEVICE(0x2357, 0x0111)}, /* TP-Link TL-WN727N v5.21 */
        {}      /* Terminating entry */
};

Перекомпилировал драйвер и заново его проинсталлировал в системе.

И уж на этот раз все завелось. Лампочка на адаптере загорелась и в списке сетевых интерфейсов появилось новое устройство.

Просмотр беспроводных интерфейсов выдает следующее:

pi@raspberrypi:/home/pi/rtl8188eu# iwconfig
eth0      no wireless extensions.

lo        no wireless extensions.

wlan0     unassociated  ESSID:""  Nickname:"<WIFI@REALTEK>"
          Mode:Auto  Frequency=2.412 GHz  Access Point: Not-Associated   
          Sensitivity:0/0  
          Retry:off   RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=0/100  Signal level=0 dBm  Noise level=0 dBm
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

Бонус для тех кто дочитал до конца

Помните как я говорил, что не важно какая максимальная скорость заявлена на вашем адаптере?
Так вот, на малинке(до выхода модели 4) все устройства(в том числе и ethernet адаптер) сидят на одной шине usb. Здорово, правда? И поэтому пропускная способность шины usb делится между всеми устройствами на ней. При замере скорости и через ethernet, и через usb wi-fi (подключенные к 1 роутеру) и по воздуху, и по проводу выдавало в районе 20Мбит/с.

P.S. Вообще данный гайд по компиляции драйвера под этот конкретный адаптер справедлив не только на RPI. Я потом его повторил и на своем десктопе с Linux Mint — там тоже все заработало. Просто вам точно так же нужно скачать нужные заголовочные файлы для вашей используемой версии ядра.

UPD. Знающие люди подсказали: чтобы не зависеть от версии ядра нужно собирать и устанавливать драйверы с помощью dkms. В readme к драйверу этот вариант тоже есть

pi@raspberrypi:/home/pi# sudo dkms add ./rtl8188eu
pi@raspberrypi:/home/pi# sudo dkms build 8188eu/1.0
pi@raspberrypi:/home/pi# sudo dkms install 8188eu/1.0

UPD2. Предложеный патч для device id был принят в мейнстрим ветку репозитория lwfinger/rtl8188eu.

Ссылки
RPi USB Wi-Fi Adapters
Gitbub lwfinger/rtl8188eu
usb.ids
rpi-source

Источник: habr.com