text: /**
   * @file
   * Ethernet Interface Skeleton
   *
   */
  
  /*
   * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without modification,
   * are permitted provided that the following conditions are met:
   *
   * 1. Redistributions of source code must retain the above copyright notice,
   *    this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright notice,
   *    this list of conditions and the following disclaimer in the documentation
   *    and/or other materials provided with the distribution.
   * 3. The name of the author may not be used to endorse or promote products
   *    derived from this software without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
   * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
   * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
   * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
   * OF SUCH DAMAGE.
   *
   * This file is part of the lwIP TCP/IP stack.
   *
   * Author: Adam Dunkels <adam@sics.se>
   *
   */
  
  /*
   * This file is a skeleton for developing Ethernet network interface
   * drivers for lwIP. Add code to the low_level functions and do a
   * search-and-replace for the word "ethernetif" to replace it with
   * something that better describes your network interface.
   */
  
  #include "include.h"
  
  #include "lwip/opt.h"
  #include "lwip/def.h"
  #include "lwip/mem.h"
  #include "lwip/pbuf.h"
  #include "lwip/sys.h"
  #include <lwip/stats.h>
  #include <lwip/snmp.h>
  #include "ethernetif.h"
  
  #include <stdio.h>
  #include <string.h>
  
  #include "netif/etharp.h"
  
  #include "lwip_netif_address.h"
  
  #include "sa_station.h"
  
  #include "drv_model_pub.h"
  #include "mem_pub.h"
  #include "common.h"
  
  #include "hostapd_cfg.h"
  
  #include "sk_intf.h"
  #include "rw_pub.h"
  #include "bk_rtos_pub.h"
  #include "param_config.h"
  
  /* Define those to better describe your network interface. */
  #define IFNAME0 'e'
  #define IFNAME1 'n'
  
  #include "uart_pub.h"
  
  #define ETH_INTF_DEBUG
  #ifdef ETH_INTF_DEBUG
  #define ETH_INTF_PRT      warning_prf
  #define ETH_INTF_WARN     warning_prf
  #define ETH_INTF_FATAL    fatal_prf
  #else
  #define ETH_INTF_PRT      null_prf
  #define ETH_INTF_WARN     null_prf
  #define ETH_INTF_FATAL    null_prf
  #endif
  
  extern void *net_get_sta_handle(void);
  extern void *net_get_uap_handle(void);
  extern void wifi_get_mac_address(char *mac, u8 type);
  extern void *net_get_netif_handle(uint8_t iface);
  
  extern int bmsg_tx_sender(struct pbuf *p, uint32_t vif_idx);
      
  /* Forward declarations. */
  void ethernetif_input(int iface, struct pbuf *p);
  
  /**
   * In this function, the hardware should be initialized.
   * Called from ethernetif_init().
   *
   * @param netif the already initialized lwip network interface structure
   *        for this ethernetif
   */
  
  const char wlan_name[][6] = 
  {
      "wlan0\0",
      "wlan1\0",
      "wlan2\0",
      "wlan3\0",    
  };
  static void low_level_init(struct netif *netif)
  {
      VIF_INF_PTR vif_entry = (VIF_INF_PTR)(netif->state);
      u8 *macptr = (u8*)&vif_entry->mac_addr;
      
  #if LWIP_NETIF_HOSTNAME
      /* Initialize interface hostname */
      netif->hostname = (char*)&wlan_name[vif_entry->index];
  #endif /* LWIP_NETIF_HOSTNAME */    
  
  	//wifi_get_mac_address((char *)wireless_mac, type);
  	
      /* set MAC hardware address length */
      ETH_INTF_PRT("enter low level!\r\n");
      ETH_INTF_PRT("mac %2x:%2x:%2x:%2x:%2x:%2x\r\n", macptr[0], macptr[1], macptr[2],
                   macptr[3], macptr[4], macptr[5]);
      
      netif->hwaddr_len = ETHARP_HWADDR_LEN;
      os_memcpy(netif->hwaddr, macptr, ETHARP_HWADDR_LEN);
      /* maximum transfer unit */
      netif->mtu = 1500;
      /* device capabilities */
      /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
      netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
      ETH_INTF_PRT("leave low level!\r\n");
  }
  
  /**
   * This function should do the actual transmission of the packet. The packet is
   * contained in the pbuf that is passed to the function. This pbuf
   * might be chained.
   *
   * @param netif the lwip network interface structure for this ethernetif
   * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
   * @return ERR_OK if the packet could be sent
   *         an err_t value if the packet couldn't be sent
   *
   * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
   *       strange results. You might consider waiting for space in the DMA queue
   *       to become availale since the stack doesn't retry to send a packet
   *       dropped because of memory failure (except for the TCP timers).
   */
  static err_t low_level_output(struct netif *netif, struct pbuf *p)
  {
  	int ret;
  	err_t err = ERR_OK;
      uint8_t vif_idx = rwm_mgmt_get_netif2vif(netif);
  
  	//os_printf("output:%x\r\n", p);
  	ret = bmsg_tx_sender(p, (uint32_t)vif_idx);
  	if(0 != ret)
  	{
  		err = ERR_TIMEOUT;
  	}
  
      return err;
  }
  
  /**
   * This function should be called when a packet is ready to be read
   * from the interface. It uses the function low_level_input() that
   * should handle the actual reception of bytes from the network
   * interface. Then the type of the received packet is determined and
   * the appropriate input function is called.
   *
   * @param netif the lwip network interface structure for this ethernetif
   */
  void
  ethernetif_input(int iface, struct pbuf *p)
  {
      struct eth_hdr *ethhdr;
  	struct netif *netif;
  
  	if (p->len <= SIZEOF_ETH_HDR) {
  		pbuf_free(p);
  		return; 
  	}   
  
  	netif = rwm_mgmt_get_vif2netif((uint8_t)iface);
      if(!netif) {
          //ETH_INTF_PRT("ethernetif_input no netif found %d\r\n", iface);
          pbuf_free(p);
          p = NULL;
          return;
      }
          
      /* points to packet payload, which starts with an Ethernet header */
      ethhdr = p->payload;
  
      switch (htons(ethhdr->type))
      {
          /* IP or ARP packet? */
      case ETHTYPE_IP:
      case ETHTYPE_ARP:
  #if PPPOE_SUPPORT
          /* PPPoE packet? */
      case ETHTYPE_PPPOEDISC:
      case ETHTYPE_PPPOE:
  #endif /* PPPOE_SUPPORT */
          /* full packet send to tcpip_thread to process */
          if (netif->input(p, netif) != ERR_OK)    // ethernet_input
          {
              LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n"));
              pbuf_free(p);
              p = NULL;
          }
          break;
  		
      case ETHTYPE_EAPOL:
  	 	ke_l2_packet_tx(p->payload, p->len, iface);
  		pbuf_free(p);
  		p = NULL;
          break;
  		
      default:
          pbuf_free(p);
          p = NULL;
          break;
      }
  
  }
  
  /**
   * Should be called at the beginning of the program to set up the
   * network interface. It calls the function low_level_init() to do the
   * actual setup of the hardware.
   *
   * This function should be passed as a parameter to netif_add().
   *
   * @param netif the lwip network interface structure for this ethernetif
   * @return ERR_OK if the loopif is initialized
   *         ERR_MEM if private data couldn't be allocated
   *         any other err_t on error
   */
  err_t
  ethernetif_init(struct netif *netif)
  {
      LWIP_ASSERT("netif != NULL", (netif != NULL));
  
      /*
       * Initialize the snmp variables and counters inside the struct netif.
       * The last argument should be replaced with your link speed, in units
       * of bits per second.
       */
      NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
  
      netif->name[0] = IFNAME0;
      netif->name[1] = IFNAME1;
      /* We directly use etharp_output() here to save a function call.
       * You can instead declare your own function an call etharp_output()
       * from it if you have to do some checks before sending (e.g. if link
       * is available...) */
      netif->output = etharp_output;
      netif->linkoutput = low_level_output;
  
      /* initialize the hardware */
      low_level_init(netif);
  
      return ERR_OK;
  }
  
  /**
   * Should be called at the beginning of the program to set up the
   * network interface. It calls the function low_level_init() to do the
   * actual setup of the hardware.
   *
   * This function should be passed as a parameter to netifapi_netif_add().
   *
   * @param netif the lwip network interface structure for this ethernetif
   * @return ERR_OK if the loopif is initialized
   *         ERR_MEM if private data couldn't be allocated
   *         any other err_t on error
   */
  err_t lwip_netif_init(struct netif *netif)
  {
  	LWIP_ASSERT("netif != NULL", (netif != NULL));
  
  	/*
  	 * Initialize the snmp variables and counters inside the struct netif.
  	 * The last argument should be replaced with your link speed, in units
  	 * of bits per second.
  	 */
  	NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000);
  
  	netif->name[0] = IFNAME0;
  	netif->name[1] = IFNAME1;
  	/* We directly use etharp_output() here to save a function call.
  	 * You can instead declare your own function an call etharp_output()
  	 * from it if you have to do some checks before sending (e.g. if link
  	 * is available...) */
  	netif->output = etharp_output;
  	netif->linkoutput = low_level_output;
  #ifdef CONFIG_IPV6
  	netif->output_ip6 = ethip6_output;
  #endif
  
  	/* initialize the hardware */
  	low_level_init(netif);
  	return ERR_OK;
  }
  
  err_t lwip_netif_uap_init(struct netif *netif)
  {
  	LWIP_ASSERT("netif != NULL", (netif != NULL));
  
  	//netif->state = NULL;
  	netif->name[0] = 'u';
  	netif->name[1] = 'a';
  	/* We directly use etharp_output() here to save a function call.
  	 * You can instead declare your own function an call etharp_output()
  	 * from it if you have to do some checks before sending (e.g. if link
  	 * is available...) */
  	netif->output = etharp_output;
  	netif->linkoutput = low_level_output;
  
  	/* initialize the hardware */
  	low_level_init(netif);
  
  	return ERR_OK;
  }
  
  // eof
  