Linux cfg80211 netdev and wiphy vendor command

收錄在 Ameba 的一百篇

--
續前篇: cfg80211 wiphy


類似前篇做 wiphy 的方式, 我們來做 net device

在 聖經 Linux Device Drivers  : Chapter 17, Network Drivers 中,
也有提到, 如何做一個 虛擬的網路驅動程式 - snull
不過這是蠻早期的 Linux.

也可以參考這篇, 如何寫一個 Linux wireless device driver, github

底下實驗範例程式在 - github

--
netdev

可以透過 alloc_netdev() 和 register_netdev() 來做
  NDEV_NAME 我們宣告 "wi"
  NET_NAME_ENUM 是 kernel 宣告
  ether_setup() 是 kernel function


在 net_device_ops, 我們可以只簡單做一個 .ndo_start_xmit 給 TX function




這樣執行後 ifconfig -a 會看到 wi0 , 也可以做 ifconfig up / down

--
相對應 register_netdev() 是 unregister_netdev()
相對應 wiphy_register() 是 wiphy_unregister()
相對應 alloc_netdev()  和 wiphy_new() 是可以直接 kfree()

--

netlink mutex locking / unlocking,

我們可以看 register_netdev() 這個 function,
如果直接使用 register_netdevice(), 就會因為沒有做 mutex lock 而產生 assertion 錯誤.

int register_netdev(struct net_device *dev)
{
    int err;

    rtnl_lock();
    err = register_netdevice(dev);                                                                                     
    rtnl_unlock();
    return err;
}

--
接下來我們看 wiphy 中的 vendor commands

當 user space program 要和 kernel space 的 wifi 溝通時, 是透過 netlink 介面,
也就是 nl80211 (include/uapi/linux/nl80211.h)

可以參考之前介紹的 nl80211





在 Linux v5 時, wiphy vendor command 新增了 .policy, 我們先以 Linux v4.x 來實驗.
這樣只需要設定以下幾個:

1. struct wiphy_vendor_command

(1) nl80211_vendor_cmd_info

/**
 * struct nl80211_vendor_cmd_info - vendor command data
 * @vendor_id: If the %NL80211_VENDOR_ID_IS_LINUX flag is clear, then the
 * value is a 24-bit OUI; if it is set then a separately allocated ID
 * may be used, but no such IDs are allocated yet. New IDs should be
 * added to this file when needed.
 * @subcmd: sub-command ID for the command
 */
struct nl80211_vendor_cmd_info {
 __u32 vendor_id;
 __u32 subcmd;
};


這邊要填寫
   vendor_id: 也就是 24bit OUI, (參考 OUI 列表)
   subcmd: 所定義的 command id

我們先以 Google OUI : 0x001a11, subcmd id 用 0 來實驗

(2) flags

/**
 * enum wiphy_vendor_command_flags - validation flags for vendor commands
 * @WIPHY_VENDOR_CMD_NEED_WDEV: vendor command requires wdev
 * @WIPHY_VENDOR_CMD_NEED_NETDEV: vendor command requires netdev
 * @WIPHY_VENDOR_CMD_NEED_RUNNING: interface/wdev must be up & running
 * (must be combined with %_WDEV or %_NETDEV)
 */
enum wiphy_vendor_command_flags {
 WIPHY_VENDOR_CMD_NEED_WDEV = BIT(0),
 WIPHY_VENDOR_CMD_NEED_NETDEV = BIT(1),
 WIPHY_VENDOR_CMD_NEED_RUNNING = BIT(2),
};


(3) doit

int (*doit)(struct wiphy *wiphy, struct wireless_dev *wdev,
      void *data, int data_len);


範例:



我們寫一個簡單的 function, 把各 byte 的資料值相加起來.

測試:

sudo iw dev wi0 vendor recv 0x001a11 0x00 0x12 0x34 0x56 0x78

會得到:

vendor response: 14 01 00 00

也就是 0x12 + 0x34 + 0x56 + 0x78 = 0x114

事實上 Google Android 在 WIFI HAL 的實作, 也是透過  vendor command 來和 driver 溝通.

後續: vendor command policy


留言

熱門文章