329 lines
10 KiB
C
329 lines
10 KiB
C
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
|
|
* Description: HMAC module HCC layer adaptation.
|
|
* Author: kongcheng
|
|
* Create: 2020-08-04
|
|
*/
|
|
|
|
/* 头文件包含 */
|
|
#include <linux/nl80211.h>
|
|
#include "hcc_comm.h"
|
|
#include "wal_net.h"
|
|
#include "securec.h"
|
|
#include "hcc_adapt.h"
|
|
#include "oal_netbuf.h"
|
|
#include <linux/etherdevice.h>
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
#endif
|
|
|
|
/* static 函数声明 */
|
|
static oal_net_device_stats_stru* wal_netdev_get_stats(oal_net_device_stru *netdev);
|
|
static hi_s32 wal_netdev_open(oal_net_device_stru *netdev);
|
|
static hi_s32 wal_netdev_stop(oal_net_device_stru *netdev);
|
|
static hi_s32 wal_net_start_xmit(oal_netbuf_stru *netbuf, oal_net_device_stru *netdev);
|
|
static hi_s32 wal_net_device_ioctl(oal_net_device_stru *netdev, oal_ifreq_stru *ifr, hi_s32 cmd);
|
|
static hi_s32 wal_netdev_set_mac_addr(oal_net_device_stru *netdev, void *addr);
|
|
static hi_u32 wal_ioctl_get_param(oal_net_device_stru *netdev, oal_iw_request_info_stru *info, hi_void *iw,
|
|
hi_s8 *pc_extra);
|
|
static hi_u32 wal_ioctl_set_param(oal_net_device_stru *netdev, oal_iw_request_info_stru *info, hi_void *iw,
|
|
hi_s8 *pc_extra);
|
|
|
|
#define WAL_IOCTL_PRIV_SETPARAM (OAL_SIOCIWFIRSTPRIV + 0)
|
|
#define WAL_IOCTL_PRIV_GETPARAM (OAL_SIOCIWFIRSTPRIV + 1)
|
|
#define WAL_IOCTL_CMD_LEN 512
|
|
|
|
/* 全局变量定义 */
|
|
static const oal_iw_priv_args_stru g_ast_iw_priv_args[] = {
|
|
{WAL_IOCTL_PRIV_SETPARAM, OAL_IW_PRIV_TYPE_CHAR | WAL_IOCTL_CMD_LEN, 0, "SET"}, /* 字符个数为512 */
|
|
{WAL_IOCTL_PRIV_GETPARAM, 0, OAL_IW_PRIV_TYPE_CHAR | WAL_IOCTL_CMD_LEN, "GET"}, /* 字符个数为512 */
|
|
};
|
|
|
|
static const oal_iw_handler g_ast_iw_priv_handlers[] = {
|
|
(oal_iw_handler)wal_ioctl_set_param, /* SIOCWFIRSTPRIV+0 */ /* sub-ioctl set 入口 */
|
|
(oal_iw_handler)wal_ioctl_get_param, /* SIOCWFIRSTPRIV+1 */ /* sub-ioctl get 入口 */
|
|
};
|
|
|
|
oal_iw_handler_def_stru g_iw_handler_def = {
|
|
.private = g_ast_iw_priv_handlers,
|
|
.num_private = hi_array_size(g_ast_iw_priv_handlers),
|
|
.private_args = g_ast_iw_priv_args,
|
|
.num_private_args = hi_array_size(g_ast_iw_priv_args),
|
|
.get_wireless_stats = HI_NULL
|
|
};
|
|
|
|
oal_net_device_ops_stru g_wal_net_dev_ops = {
|
|
.ndo_get_stats = wal_netdev_get_stats,
|
|
.ndo_open = wal_netdev_open,
|
|
.ndo_stop = wal_netdev_stop,
|
|
.ndo_start_xmit = wal_net_start_xmit,
|
|
.ndo_do_ioctl = wal_net_device_ioctl,
|
|
.ndo_set_mac_address = wal_netdev_set_mac_addr,
|
|
};
|
|
|
|
/* 函数定义 */
|
|
/*****************************************************************************
|
|
函 数 名 : wal_netdev_get_stats
|
|
功能描述 : 获取统计信息
|
|
*****************************************************************************/
|
|
static hi_u32 wal_ioctl_get_param(oal_net_device_stru *netdev, oal_iw_request_info_stru *info, hi_void *iw,
|
|
hi_s8 *pc_extra)
|
|
{
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
static hi_u32 wal_ioctl_set_param(oal_net_device_stru *netdev, oal_iw_request_info_stru *info, hi_void *iw,
|
|
hi_s8 *pc_extra)
|
|
{
|
|
hi_u32 ret;
|
|
hi_char *payload = HI_NULL;
|
|
oal_netbuf_stru *netbuf = HI_NULL;
|
|
oal_iw_point_stru *iw_point = (oal_iw_point_stru *)iw;
|
|
if (iw_point->length > WAL_IOCTL_CMD_LEN) {
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
netbuf = (oal_netbuf_stru *)oal_netbuf_alloc(iw_point->length + HCC_HDR_TOTAL_LEN, 0, 4); /* 4: 4字节对齐 */
|
|
if (netbuf == HI_NULL) {
|
|
oam_error_log0("oal_netbuf_alloc is error\n");
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
oal_netbuf_put(netbuf, iw_point->length);
|
|
payload = oal_netbuf_data(netbuf);
|
|
(hi_void)memcpy_s(payload, iw_point->length, pc_extra, iw_point->length);
|
|
oal_netbuf_next(netbuf) = HI_NULL;
|
|
oal_netbuf_prev(netbuf) = HI_NULL;
|
|
|
|
ret = hcc_tx_data_adapt(netbuf, HCC_TYPE_MSG, HCC_SUB_TYPE_USER_MSG);
|
|
if (ret != HI_SUCCESS) {
|
|
oam_error_log0("hcc_tx_data_adapt is error\n");
|
|
oal_netbuf_free(netbuf);
|
|
}
|
|
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
static oal_net_device_stats_stru* wal_netdev_get_stats(oal_net_device_stru *netdev)
|
|
{
|
|
oal_net_device_stats_stru *stats = HI_NULL;
|
|
|
|
if (netdev == HI_NULL) {
|
|
return HI_NULL;
|
|
}
|
|
|
|
stats = (oal_net_device_stats_stru *)&(netdev->stats);
|
|
stats->rx_packets = 10; /* rx_packets 10 */
|
|
stats->rx_bytes = 10; /* rx_bytes 10 */
|
|
stats->tx_packets = 10; /* tx_packets 10 */
|
|
stats->tx_bytes = 10; /* tx_bytes 10 */
|
|
|
|
return stats;
|
|
}
|
|
|
|
static hi_s32 wal_netdev_open(oal_net_device_stru *netdev)
|
|
{
|
|
if ((oal_netdevice_flags(netdev) & OAL_IFF_RUNNING) == 0) {
|
|
oal_netdevice_flags(netdev) |= OAL_IFF_RUNNING;
|
|
}
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
static hi_s32 wal_netdev_stop(oal_net_device_stru *netdev)
|
|
{
|
|
if ((oal_netdevice_flags(netdev) & OAL_IFF_RUNNING) != 0) {
|
|
oal_netdevice_flags(netdev) &= (~OAL_IFF_RUNNING);
|
|
}
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
/* 注册给TCP/IP 协议栈的XMIT回调 */
|
|
static oal_net_dev_tx_enum wal_net_start_xmit(oal_netbuf_stru *netbuf, oal_net_device_stru *netdev)
|
|
{
|
|
hi_u32 ret;
|
|
|
|
if ((netbuf == HI_NULL) || (netdev == HI_NULL)) {
|
|
oam_error_log2("wal_bridge_vap_xmit:: invalid params[%p][%p]", netbuf, netdev);
|
|
return OAL_NETDEV_TX_OK;
|
|
}
|
|
|
|
if ((oal_netdevice_flags(netdev) & OAL_IFF_RUNNING) == 0) {
|
|
oam_error_log0("wal_net_start_xmit:: netdev is not RUNNING");
|
|
oal_netbuf_free(netbuf);
|
|
return OAL_NETDEV_TX_OK;
|
|
}
|
|
|
|
oal_netbuf_stru *skb_buff = oal_netbuf_alloc(oal_netbuf_len(netbuf), 0, 0);
|
|
if (skb_buff == HI_NULL) {
|
|
oam_error_log0("***wal_net_start_xmit:: alloc_sbk failed");
|
|
oal_netbuf_free(netbuf);
|
|
return OAL_NETDEV_TX_OK;
|
|
}
|
|
|
|
memcpy_s(oal_netbuf_data(skb_buff), oal_netbuf_len(netbuf), oal_netbuf_data(netbuf), oal_netbuf_len(netbuf));
|
|
oal_netbuf_len(skb_buff) = oal_netbuf_len(netbuf);
|
|
|
|
oal_netbuf_free(netbuf);
|
|
|
|
oal_netbuf_next(skb_buff) = HI_NULL;
|
|
oal_netbuf_prev(skb_buff) = HI_NULL;
|
|
|
|
ret = hcc_tx_data_adapt(skb_buff, HCC_TYPE_DATA, HCC_SUB_TYPE_IP_DATA);
|
|
if (ret != HI_SUCCESS) {
|
|
oal_netbuf_free(skb_buff);
|
|
}
|
|
|
|
return OAL_NETDEV_TX_OK;
|
|
}
|
|
|
|
static hi_s32 wal_net_device_ioctl(oal_net_device_stru *netdev, oal_ifreq_stru *ifr, hi_s32 cmd)
|
|
{
|
|
hi_u32 ret = HI_SUCCESS;
|
|
|
|
if ((netdev == HI_NULL) || (ifr == HI_NULL) || (ifr->ifr_data == HI_NULL)) {
|
|
oam_error_log2("{wal_net_device_ioctl::pst_dev %p, pst_ifr %p!}",
|
|
(uintptr_t)netdev, (uintptr_t)ifr);
|
|
return HI_FAILURE;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
函 数 名 : wal_netdev_set_mac_addr
|
|
功能描述 : 设置mac地址
|
|
输入参数 : netdev: 网络设备
|
|
addr : 地址
|
|
*****************************************************************************/
|
|
static hi_s32 wal_netdev_set_mac_addr(oal_net_device_stru *netdev, void *addr)
|
|
{
|
|
oal_sockaddr_stru *mac_addr = HI_NULL;
|
|
|
|
if ((netdev == HI_NULL) || (addr == HI_NULL)) {
|
|
oam_error_log2("{wal_netdev_set_mac_addr::pst_net_dev or p_addr null ptr error %p, %p!}",
|
|
(uintptr_t)netdev, (uintptr_t)addr);
|
|
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
if (oal_netif_running(netdev)) {
|
|
oam_warning_log0("{wal_netdev_set_mac_addr::cannot set address; device running!}");
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
mac_addr = (oal_sockaddr_stru *)addr;
|
|
|
|
if (ether_is_multicast(mac_addr->sa_data)) {
|
|
oam_warning_log0("{wal_netdev_set_mac_addr::can not set group/broadcast addr!}");
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
if (memcpy_s((netdev->dev_addr), WLAN_MAC_ADDR_LEN, (mac_addr->sa_data), WLAN_MAC_ADDR_LEN) != EOK) {
|
|
oam_error_log0("{wal_netdev_set_mac_addr::mem safe function err!}");
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
/* 1131如果return则无法通过命令配置mac地址到寄存器 */
|
|
/* when sta and ap are coexist,close the line "return HI_SUCCESS" DTS2016050607426 */
|
|
/* set mac address,need open the following line,DTS2016102403276 */
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
oal_net_device_ops_stru* wal_get_net_dev_ops(hi_void)
|
|
{
|
|
return &g_wal_net_dev_ops;
|
|
}
|
|
|
|
oal_iw_handler_def_stru* wal_get_g_iw_handler_def(hi_void)
|
|
{
|
|
return &g_iw_handler_def;
|
|
}
|
|
|
|
hi_u32 wal_net_register_netdev(oal_net_device_stru* netdev)
|
|
{
|
|
if (netdev == HI_NULL) {
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
return register_netdev(netdev);
|
|
}
|
|
|
|
hi_s32 wal_rx_data_proc(oal_netbuf_stru *netbuf)
|
|
{
|
|
oal_net_device_stru *netdev = oal_get_netdev_by_name("wlan0");
|
|
if (netdev == HI_NULL) {
|
|
oam_info_log0("wal_rx_data_proc:: netdev is NULL");
|
|
oal_netbuf_free(netbuf);
|
|
return HI_FAIL;
|
|
}
|
|
|
|
oal_dev_put(netdev);
|
|
|
|
/* 对protocol模式赋值 */
|
|
oal_netbuf_protocol(netbuf) = eth_type_trans(netbuf, netdev);
|
|
|
|
return netif_rx_ni(netbuf);
|
|
}
|
|
|
|
hi_s32 wal_init_netdev(hi_u8 type, oal_net_device_stru *netdev)
|
|
{
|
|
netdev->wireless_handlers = wal_get_g_iw_handler_def();
|
|
netdev->netdev_ops = wal_get_net_dev_ops();
|
|
|
|
oal_netdevice_destructor(netdev) = wal_net_free_netdev;
|
|
oal_netdevice_ifalias(netdev) = HI_NULL;
|
|
oal_netdevice_watchdog_timeo(netdev) = 5; /* 固定设置为 5 */
|
|
oal_netdevice_qdisc(netdev, HI_NULL);
|
|
|
|
oal_netdevice_flags(netdev) &= ~OAL_IFF_RUNNING; /* 将net device的flag设为down */
|
|
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
hi_s32 netdev_register(hi_void)
|
|
{
|
|
oal_net_device_stru *netdev = HI_NULL;
|
|
hi_char dev_name[OAL_IF_NAME_SIZE] = "wlan0";
|
|
|
|
netdev = wal_net_alloc_netdev(0, dev_name, oal_ether_setup);
|
|
if (netdev == HI_NULL) {
|
|
oam_error_log0("regiser_netdev:: netdev is NULL");
|
|
return HI_FAILURE;
|
|
}
|
|
|
|
hi_s32 ret = wal_init_netdev(NL80211_IFTYPE_STATION, netdev);
|
|
if (ret != HI_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
ret = wal_net_register_netdev(netdev);
|
|
if (ret != HI_SUCCESS) {
|
|
oam_warning_log1("{regiser_netdev:: wal_net_register_netdev failed[%d]}", ret);
|
|
wal_net_free_netdev(netdev);
|
|
return ret;
|
|
}
|
|
|
|
oam_warning_log0("netdev_register SUCCESSFULLY");
|
|
return HI_SUCCESS;
|
|
}
|
|
|
|
hi_void netdev_unregister(hi_void)
|
|
{
|
|
oal_net_device_stru *netdev = oal_get_netdev_by_name("wlan0");
|
|
if (netdev == HI_NULL) {
|
|
oam_error_log0("netdev_unregister:: netdev is NULL");
|
|
return;
|
|
}
|
|
|
|
oal_dev_put(netdev);
|
|
oal_netdevice_flags(netdev) &= ~OAL_IFF_RUNNING;
|
|
oal_net_unregister_netdev(netdev);
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
#if __cplusplus
|
|
}
|
|
#endif
|
|
#endif |