pure sdk for main
This commit is contained in:
@@ -0,0 +1,625 @@
|
||||
#include "sys_config.h"
|
||||
#include "typesdef.h"
|
||||
#include "list.h"
|
||||
#include "dev.h"
|
||||
#include "devid.h"
|
||||
#include "osal/string.h"
|
||||
#include "osal/mutex.h"
|
||||
#include "osal/work.h"
|
||||
#include "osal/semaphore.h"
|
||||
#include "osal/timer.h"
|
||||
#include "hal/netdev.h"
|
||||
#include "hal/dma.h"
|
||||
#include "hal/netdev.h"
|
||||
#include "lib/heap/sysheap.h"
|
||||
#include "lib/umac/ieee80211.h"
|
||||
#include "lib/skb/skb.h"
|
||||
#include "lib/skb/skb_list.h"
|
||||
#include "lib/net/utils.h"
|
||||
#include "syscfg.h"
|
||||
|
||||
#ifndef WIFI_DEV_ICMP_MONITOR
|
||||
#define WIFI_DEV_ICMP_MONITOR 1
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
#define ADDR_IDX(addr) (addr[5]&0x0f)
|
||||
#define MAC_ENTRY_TMO (5*60*1000)
|
||||
#define MAC_ENTRY_COUNT_MAX (256)
|
||||
#define MAC_ENTRY_COUNT_WARNING (100)
|
||||
|
||||
struct mac_table_entry {
|
||||
struct list_head list;
|
||||
uint64 lifetime;
|
||||
uint8 addr[6];
|
||||
struct netdev *ndev;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct wifi_dev {
|
||||
struct netdev wifi;
|
||||
netdev_input_cb input_cb;
|
||||
void *input_priv;
|
||||
uint8 addr[6];
|
||||
uint8 ifidx;
|
||||
uint8 icmp_mntr: 1, bridge_mode: 1;
|
||||
uint32 no_mem;
|
||||
uint32 rx_data, tx_data;
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
struct os_task fw_task;
|
||||
struct skb_list fw_list;
|
||||
struct os_semaphore fw_sema;
|
||||
struct os_mutex lock;
|
||||
struct os_work work;
|
||||
uint32 mac_count;
|
||||
struct list_head mac_table[16];
|
||||
uint32 brdev_cnt;
|
||||
struct netdev *brdev_list[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
#if WIFI_DEV_ICMP_MONITOR
|
||||
static void wifi_dev_icmp_monitor(struct wifi_dev *wifi, uint8 *data, uint8 tx)
|
||||
{
|
||||
if (wifi->icmp_mntr) {
|
||||
if (get_unaligned_be16(data + 12) == 0x800 && data[23] == 0x1) {
|
||||
if (data[34] == 8 || data[34] == 0) {
|
||||
uint16 sn = get_unaligned_be16(data + 40);
|
||||
os_printf(KERN_NOTICE"wifi: %s imcp %s, sn:%d\r\n", tx ? "TX" : "RX", data[34] == 8 ? "Echo " : "Reply", sn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8 *wifi_dev_scatter_offset(scatter_data *data, uint32 count, uint32 off)
|
||||
{
|
||||
uint8 i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (off <= data[i].size) {
|
||||
return data[i].addr + off;
|
||||
}
|
||||
off -= data[i].size;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wifi_dev_icmp_monitor_scatter(struct wifi_dev *wifi, scatter_data *data, uint32 count, uint8 tx)
|
||||
{
|
||||
uint8 *ptr;
|
||||
uint16 p1, sn;
|
||||
uint8 p2, p3;
|
||||
if (wifi->icmp_mntr) {
|
||||
ptr = wifi_dev_scatter_offset(data, count, 12);
|
||||
if (ptr == NULL) return;
|
||||
p1 = get_unaligned_be16(ptr);
|
||||
|
||||
ptr = wifi_dev_scatter_offset(data, count, 23);
|
||||
if (ptr == NULL) return;
|
||||
p2 = *ptr;
|
||||
|
||||
if (p1 == 0x800 && p2 == 0x1) {
|
||||
ptr = wifi_dev_scatter_offset(data, count, 34);
|
||||
if (ptr == NULL) return;
|
||||
p3 = *ptr;
|
||||
if (p3 == 8 || p3 == 0) {
|
||||
ptr = wifi_dev_scatter_offset(data, count, 40);
|
||||
if (ptr == NULL) return;
|
||||
sn = get_unaligned_be16(ptr);
|
||||
os_printf(KERN_NOTICE"wifi: %s imcp %s, sn:%d\r\n", tx ? "TX" : "RX", p3 == 8 ? "Echo " : "Reply", sn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define wifi_dev_icmp_monitor(...)
|
||||
#define wifi_dev_icmp_monitor_scatter(...)
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
static int32 wifi_dev_hook_input_data(struct netdev *ndev, uint8 *data, uint32 len)
|
||||
{
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)ndev;
|
||||
uint8 ifidx = wifi->ifidx == WIFI_MODE_APSTA ? WIFI_MODE_STA : wifi->ifidx;
|
||||
if (IS_MCAST_ADDR(data)) {
|
||||
return IEEE80211_PKTHDL_CONTINUE;
|
||||
}
|
||||
return ieee80211_hook_ext_data(ifidx, 1, data, len);
|
||||
}
|
||||
|
||||
static struct mac_table_entry *wifi_brdev_get_mac_entry(struct wifi_dev *wifi, uint8 *addr)
|
||||
{
|
||||
struct mac_table_entry *entry = NULL;
|
||||
struct list_head *head = &wifi->mac_table[ADDR_IDX(addr)];
|
||||
|
||||
if (!list_empty(head)) {
|
||||
list_for_each_entry(entry, head, list) {
|
||||
if (MAC_EQU(entry->addr, addr)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mac_table_entry *wifi_brdev_del_mac_entry(struct wifi_dev *wifi, uint8 *addr)
|
||||
{
|
||||
struct mac_table_entry *entry;
|
||||
|
||||
os_mutex_lock(&wifi->lock, osWaitForever);
|
||||
entry = wifi_brdev_get_mac_entry(wifi, addr);
|
||||
if (entry) {
|
||||
list_del(&entry->list);
|
||||
os_free(entry);
|
||||
wifi->mac_count--;
|
||||
}
|
||||
os_mutex_unlock(&wifi->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wifi_brdev_clear_mac_entry(struct wifi_dev *wifi)
|
||||
{
|
||||
int32 i = 0;
|
||||
struct list_head *head;
|
||||
struct mac_table_entry *pos, *n;
|
||||
|
||||
os_mutex_lock(&wifi->lock, osWaitForever);
|
||||
for (i = 0; i < 16; i++) {
|
||||
head = &wifi->mac_table[i];
|
||||
list_for_each_entry_safe(pos, n, head, list) {
|
||||
list_del(&pos->list);
|
||||
os_free(pos);
|
||||
wifi->mac_count--;
|
||||
}
|
||||
}
|
||||
os_mutex_unlock(&wifi->lock);
|
||||
}
|
||||
|
||||
static int32 wifi_brdev_need_forward(struct wifi_dev *wifi, struct netdev *brdev, uint8 *dest)
|
||||
{
|
||||
int32 ret = 0;
|
||||
struct mac_table_entry *entry = NULL;
|
||||
|
||||
if (IS_MCAST_ADDR(dest)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
os_mutex_lock(&wifi->lock, osWaitForever);
|
||||
entry = wifi_brdev_get_mac_entry(wifi, dest);
|
||||
ret = (entry && entry->ndev == brdev);
|
||||
os_mutex_unlock(&wifi->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wifi_brdev_mac_table_expired(struct wifi_dev *wifi)
|
||||
{
|
||||
int32 i = 0;
|
||||
struct list_head *head;
|
||||
struct mac_table_entry *entry;
|
||||
uint32 tmo = wifi->mac_count > MAC_ENTRY_COUNT_WARNING ? 500 : MAC_ENTRY_TMO;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
head = &wifi->mac_table[i];
|
||||
entry = list_first_entry_or_null(head, struct mac_table_entry, list);
|
||||
if (entry && TIME_AFTER(os_jiffies(), entry->lifetime + os_msecs_to_jiffies(tmo))) {
|
||||
list_del(&entry->list);
|
||||
os_free(entry);
|
||||
wifi->mac_count--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_brdev_update_mac_table(struct wifi_dev *wifi, struct netdev *ndev, uint8 *addr)
|
||||
{
|
||||
struct mac_table_entry *entry;
|
||||
struct list_head *head = &wifi->mac_table[ADDR_IDX(addr)];
|
||||
|
||||
os_mutex_lock(&wifi->lock, osWaitForever);
|
||||
wifi_brdev_mac_table_expired(wifi);
|
||||
|
||||
entry = wifi_brdev_get_mac_entry(wifi, addr);
|
||||
if (entry) {
|
||||
entry->ndev = ndev;
|
||||
entry->lifetime = os_jiffies();
|
||||
list_del(&entry->list);
|
||||
list_add(&entry->list, head);
|
||||
} else if (wifi->mac_count < MAC_ENTRY_COUNT_MAX) {
|
||||
entry = os_malloc(sizeof(struct mac_table_entry));
|
||||
if (entry) {
|
||||
entry->ndev = ndev;
|
||||
entry->lifetime = os_jiffies();
|
||||
os_memcpy(entry->addr, addr, 6);
|
||||
list_add(&entry->list, head);
|
||||
wifi->mac_count++;
|
||||
}
|
||||
}
|
||||
os_mutex_unlock(&wifi->lock);
|
||||
}
|
||||
|
||||
static void wifi_brdev_save_fwdata(struct wifi_dev *wifi, struct netdev *ndev, uint8 *data, uint32 size)
|
||||
{
|
||||
struct sk_buff *skb = alloc_tx_skb(size);
|
||||
if (skb) {
|
||||
skb->sta = ndev;
|
||||
hw_memcpy(skb->data, data, size);
|
||||
skb_put(skb, size);
|
||||
skb_list_queue(&wifi->fw_list, skb);
|
||||
os_sema_up(&wifi->fw_sema);
|
||||
}
|
||||
}
|
||||
|
||||
static void wifi_brdev_forward_task(void *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)arg;
|
||||
|
||||
while (1) {
|
||||
os_sema_down(&wifi->fw_sema, osWaitForever);
|
||||
skb = skb_list_dequeue(&wifi->fw_list);
|
||||
if (skb) {
|
||||
netdev_send_data((struct netdev *)skb->sta, skb->data, skb->len);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32 wifi_brdev_list_forward(struct wifi_dev *wifi, uint8 *data, uint32 len, int32 *err)
|
||||
{
|
||||
int32 i = 0;
|
||||
uint8 mcast = IS_MCAST_ADDR(data);
|
||||
|
||||
if (!wifi->bridge_mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < wifi->brdev_cnt; i++) {
|
||||
if (wifi->brdev_list[i] && wifi_brdev_need_forward(wifi, wifi->brdev_list[i], data)) {
|
||||
*err = netdev_send_data(wifi->brdev_list[i], data, len);
|
||||
if (!mcast) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32 wifi_brdev_list_forward_scatter(struct wifi_dev *wifi, scatter_data *data, uint32 count, int32 *err)
|
||||
{
|
||||
int32 i = 0;
|
||||
uint8 mcast = IS_MCAST_ADDR(data[0].addr);
|
||||
|
||||
if (!wifi->bridge_mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < wifi->brdev_cnt; i++) {
|
||||
if (wifi->brdev_list[i] && wifi_brdev_need_forward(wifi, wifi->brdev_list[i], data[0].addr)) {
|
||||
*err = netdev_send_scatter_data(wifi->brdev_list[i], data, count);
|
||||
if (!mcast) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wifi_brdev_input_cb(struct netdev *ndev, uint8 *data, uint32 size, void *priv)
|
||||
{
|
||||
int32 i = 0;
|
||||
uint32 mcast;
|
||||
void *input_priv;
|
||||
netdev_input_cb input_cb;
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)priv;
|
||||
uint8 ifidx = (wifi->ifidx == WIFI_MODE_APSTA ? 0 : wifi->ifidx);
|
||||
|
||||
if (!wifi->bridge_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
mcast = disable_irq();
|
||||
input_cb = wifi->input_cb;
|
||||
input_priv = wifi->input_priv;
|
||||
enable_irq(mcast);
|
||||
|
||||
mcast = IS_MCAST_ADDR(data);
|
||||
wifi_brdev_update_mac_table(wifi, ndev, data + 6);
|
||||
|
||||
if (input_cb && (mcast || MAC_EQU(data, wifi->addr))) {
|
||||
wifi_dev_icmp_monitor(wifi, data, 0);
|
||||
input_cb(&wifi->wifi, data, size, input_priv);
|
||||
if (!mcast) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; wifi->brdev_cnt > 1 && i < wifi->brdev_cnt; i++) {
|
||||
if (ndev != wifi->brdev_list[i] && wifi_brdev_need_forward(wifi, wifi->brdev_list[i], data)) {
|
||||
wifi_brdev_save_fwdata(wifi, wifi->brdev_list[i], data, size);
|
||||
if (!mcast) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wifi->tx_data++;
|
||||
wifi->wifi.tx_bytes += size;
|
||||
ieee80211_tx(ifidx, data, size);
|
||||
}
|
||||
|
||||
static int32 wifi_brdev_work(struct os_work *work)
|
||||
{
|
||||
struct wifi_dev *wifi = container_of(work, struct wifi_dev, work);
|
||||
|
||||
os_mutex_lock(&wifi->lock, osWaitForever);
|
||||
wifi_brdev_mac_table_expired(wifi);
|
||||
os_mutex_unlock(&wifi->lock);
|
||||
os_run_work_delay(work, 500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void wifi_brdev_open_close(struct wifi_dev *wifi, uint8 open)
|
||||
{
|
||||
int32 i = 0;
|
||||
for (i = 0; i < wifi->brdev_cnt; i++) {
|
||||
if (open) {
|
||||
netdev_open(wifi->brdev_list[i], wifi_brdev_input_cb, NULL, wifi);
|
||||
} else {
|
||||
netdev_close(wifi->brdev_list[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int32 wifi_dev_open(struct netdev *ndev, netdev_input_cb cb, netdev_event_cb evt_cb, void *priv)
|
||||
{
|
||||
uint32 flags;
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)ndev;
|
||||
uint8 ifidx = (wifi->ifidx == WIFI_MODE_APSTA ? WIFI_MODE_STA : wifi->ifidx);
|
||||
|
||||
if (cb) {
|
||||
flags = disable_irq();
|
||||
wifi->input_cb = cb;
|
||||
wifi->input_priv = priv;
|
||||
enable_irq(flags);
|
||||
}
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
wifi_brdev_open_close(wifi, 1);
|
||||
os_run_work_delay(&wifi->work, 500);
|
||||
#endif
|
||||
|
||||
return ieee80211_iface_start(ifidx);
|
||||
}
|
||||
|
||||
static int32 wifi_dev_close(struct netdev *ndev)
|
||||
{
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)ndev;
|
||||
uint8 ifidx = (wifi->ifidx == WIFI_MODE_APSTA ? WIFI_MODE_STA : wifi->ifidx);
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
wifi_brdev_open_close(wifi, 0);
|
||||
wifi_brdev_clear_mac_entry(wifi);
|
||||
#endif
|
||||
|
||||
return ieee80211_iface_stop(ifidx);
|
||||
}
|
||||
|
||||
static int32 wifi_dev_send(struct netdev *ndev, uint8 *data, uint32 size)
|
||||
{
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)ndev;
|
||||
uint8 ifidx = (wifi->ifidx == WIFI_MODE_APSTA ? 0 : wifi->ifidx);
|
||||
|
||||
wifi_dev_icmp_monitor(wifi, data, 1);
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
int32 ret = RET_OK;
|
||||
if (wifi_brdev_list_forward(wifi, data, size, &ret)) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
wifi->tx_data++;
|
||||
wifi->wifi.tx_bytes += size;
|
||||
return ieee80211_tx(ifidx, (uint8 *)data, size);
|
||||
}
|
||||
|
||||
static int32 wifi_dev_scatter_send(struct netdev *ndev, scatter_data *data, uint32 count)
|
||||
{
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)ndev;
|
||||
uint8 ifidx = (wifi->ifidx == WIFI_MODE_APSTA ? 0 : wifi->ifidx);
|
||||
|
||||
wifi_dev_icmp_monitor_scatter(wifi, data, count, 1);
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
int32 ret = RET_OK;
|
||||
if (wifi_brdev_list_forward_scatter(wifi, data, count, &ret)) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
wifi->tx_data++;
|
||||
wifi->wifi.tx_bytes += scatter_data_size(data, count);
|
||||
return ieee80211_scatter_tx(ifidx, data, count);
|
||||
}
|
||||
|
||||
static int32 wifi_dev_ioctl(struct netdev *ndev, uint32 cmd, uint32 param1, uint32 param2)
|
||||
{
|
||||
int32 ret = RET_OK;
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)ndev;
|
||||
uint8 ifidx = (wifi->ifidx == WIFI_MODE_APSTA ? WIFI_MODE_STA : wifi->ifidx);
|
||||
|
||||
switch (cmd) {
|
||||
case NETDEV_IOCTL_GET_ADDR:
|
||||
ieee80211_conf_get_mac(ifidx, wifi->addr);
|
||||
os_memcpy((uint8 *)param1, wifi->addr, 6);
|
||||
break;
|
||||
case NETDEV_IOCTL_SET_ADDR:
|
||||
ieee80211_conf_set_mac(ifidx, (uint8 *)param1);
|
||||
os_memcpy(wifi->addr, (uint8 *)param1, 6);
|
||||
break;
|
||||
case NETDEV_IOCTL_GET_LINK_STATUS:
|
||||
ret = (ieee80211_conf_get_connstate(ifidx) >= WPA_GROUP_HANDSHAKE);
|
||||
break;
|
||||
case NETDEV_IOCTL_GET_LINK_SPEED:
|
||||
break;
|
||||
#if WIFI_SINGLE_DEV
|
||||
case NETDEV_IOCTL_SET_WIFI_MODE:
|
||||
wifi->ifidx = (uint8)param1;
|
||||
break;
|
||||
#endif
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
case NETDEV_IOCTL_HOOK_INPUTDATA:
|
||||
ret = !wifi_dev_hook_input_data(ndev, (uint8 *)param1, param2);
|
||||
break;
|
||||
case NETDEV_IOCTL_ENABLE_WIFIBRIDGE:
|
||||
wifi->bridge_mode = param1 ? 1 : 0;
|
||||
wifi_brdev_open_close(wifi, param1);
|
||||
break;
|
||||
#endif
|
||||
case NETDEV_IOCTL_ENABLE_ICMPMNTR:
|
||||
wifi->icmp_mntr = param1 ? 1 : 0;
|
||||
break;
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
case NETDEV_IOCTL_CLEAR_ROUTETBL:
|
||||
wifi_brdev_clear_mac_entry(wifi);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = -ENOTSUPP;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32 sys_wifi_recv(void *priv, uint8 *data, uint32 len, uint32 flags)
|
||||
{
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)priv;
|
||||
int32 ret = RET_OK;
|
||||
netdev_input_cb input_cb;
|
||||
void *input_priv;
|
||||
uint8 mcast = IS_MCAST_ADDR(data);
|
||||
|
||||
wifi->wifi.rx_bytes += len;
|
||||
wifi->rx_data++;
|
||||
|
||||
ret = disable_irq();
|
||||
input_cb = wifi->input_cb;
|
||||
input_priv = wifi->input_priv;
|
||||
enable_irq(ret);
|
||||
ret = RET_OK;
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
wifi_brdev_del_mac_entry(wifi, data + 6);
|
||||
#endif
|
||||
|
||||
if (input_cb && (mcast || MAC_EQU(data, wifi->addr))) {
|
||||
wifi_dev_icmp_monitor(wifi, data, 0);
|
||||
input_cb(&wifi->wifi, data, len, input_priv);
|
||||
if (!mcast) {
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
ret = wifi_brdev_list_forward(wifi, data, len, &ret);
|
||||
if(ret == 0 && !mcast && wifi->bridge_mode){ //NO Route: send to all interface.
|
||||
int8 i = 0;
|
||||
for (i = 0; i < wifi->brdev_cnt; i++) {
|
||||
netdev_send_data(wifi->brdev_list[i], data, len);
|
||||
}
|
||||
wifi_dev_icmp_monitor(wifi, data, len);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct netdev_hal_ops wifi_dev_ops = {
|
||||
.open = wifi_dev_open,
|
||||
.close = wifi_dev_close,
|
||||
.ioctl = wifi_dev_ioctl,
|
||||
.send_data = wifi_dev_send,
|
||||
.send_scatter_data = wifi_dev_scatter_send,
|
||||
};
|
||||
|
||||
__init void *sys_wifi_register(uint32 ifidx)
|
||||
{
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
int32 i = 0;
|
||||
uint32 brdev_list[] = {WIFI_BRIDGE_DEVLIST};
|
||||
uint32 brdev_size = ARRAY_SIZE(brdev_list) * sizeof(struct netdev *);
|
||||
#else
|
||||
uint32 brdev_size = 0;
|
||||
#endif
|
||||
|
||||
struct wifi_dev *wifi;
|
||||
uint32 dev_id = HG_WIFI0_DEVID + ifidx - 1;
|
||||
|
||||
#if WIFI_SINGLE_DEV
|
||||
dev_id = HG_WIFI0_DEVID;
|
||||
wifi = (struct wifi_dev *)dev_get(dev_id);
|
||||
if (wifi) {
|
||||
return wifi;
|
||||
}
|
||||
#endif
|
||||
|
||||
wifi = (struct wifi_dev *)os_zalloc(sizeof(struct wifi_dev) + brdev_size);
|
||||
ASSERT(wifi);
|
||||
wifi->wifi.dev.ops = (const struct devobj_ops *)&wifi_dev_ops;
|
||||
wifi->ifidx = (uint8)ifidx;
|
||||
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
os_mutex_init(&wifi->lock);
|
||||
os_sema_init(&wifi->fw_sema, 0);
|
||||
skb_list_init(&wifi->fw_list);
|
||||
OS_WORK_INIT(&wifi->work, wifi_brdev_work, 0);
|
||||
wifi->bridge_mode = 1;
|
||||
wifi->brdev_cnt = ARRAY_SIZE(brdev_list);
|
||||
for (i = 0; i < 16; i++) {
|
||||
INIT_LIST_HEAD(&wifi->mac_table[i]);
|
||||
}
|
||||
os_printf(KERN_NOTICE"wifi brigde device:");
|
||||
for (i = 0; i < wifi->brdev_cnt; i++) {
|
||||
wifi->brdev_list[i] = (struct netdev *)dev_get(brdev_list[i]);
|
||||
_os_printf("%d,", brdev_list[i]);
|
||||
ASSERT(wifi->brdev_list[i]);
|
||||
}
|
||||
_os_printf("\r\n");
|
||||
OS_TASK_INIT("fwtsk", &wifi->fw_task, wifi_brdev_forward_task, wifi, OS_TASK_PRIORITY_HIGH, 1024);
|
||||
#endif
|
||||
|
||||
ieee80211_conf_get_mac(wifi->ifidx, wifi->addr);
|
||||
dev_register(dev_id, (struct dev_obj *)wifi);
|
||||
return wifi;
|
||||
}
|
||||
|
||||
void wifi_dev_status(uint32 dev_id)
|
||||
{
|
||||
struct wifi_dev *wifi = (struct wifi_dev *)dev_get(dev_id);;
|
||||
|
||||
if (wifi == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
os_printf("WiFi Dev Status: no_mem=%u, bridge:%d\r\n", wifi->no_mem, wifi->bridge_mode);
|
||||
os_printf(" wifi: tx:%d, rx:%d, tx_bytes:%llu, rx_bytes:%llu\r\n", wifi->tx_data, wifi->rx_data, wifi->wifi.tx_bytes, wifi->wifi.rx_bytes);
|
||||
wifi->rx_data = 0;
|
||||
wifi->tx_data = 0;
|
||||
#ifdef WIFI_BRIDGE_DEVLIST
|
||||
int32 i = 0;
|
||||
os_printf(" fw_list: %d, mac_count:%d (max:%d), brdev_cnt:%d\r\n",
|
||||
wifi->fw_list.count, wifi->mac_count, MAC_ENTRY_COUNT_MAX, wifi->brdev_cnt);
|
||||
for (i = 0; i < wifi->brdev_cnt; i++) {
|
||||
if (wifi->brdev_list[i]) {
|
||||
os_printf(" brdev %d: tx:%llu, rx:%llu\r\n",
|
||||
wifi->brdev_list[i]->dev.dev_id, wifi->brdev_list[i]->tx_bytes, wifi->brdev_list[i]->rx_bytes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FMAC_EN
|
||||
__weak void hgic_custom_driver_data_handler(uint8 *data, uint16 len)
|
||||
{
|
||||
// do nothing default
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user