Дружимо 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 (навіть небо, навіть ХР) та 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 у мого, але це виявилося для малинки взагалі значення не має, про це буде написано далі). Але й найголовніше драйвера під нього вже є і ставляться просто пакетом прошивка-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Мбіт/с.

PS Взагалі цей гайд компіляції драйвера під цей конкретний адаптер справедливий не тільки на 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