2013-04-10 61 views
0

我们开发了用于电力线通信的ASIC,并正在为此开发以太网设备驱动程序。该芯片通过串行外设接口连接到我们的主处理器(iMX233 ARM9)。我们开发的内核模块在加载时注册一个以太网设备“gvspi”。收到时。我们从ASIC上通过SPI获取以太网帧并将其存储在一个字节数组中,然后分配一个sk_buff,将数组中的数据应用到该sk_buff并将其传递到TCP/IP层。在发送过程中,我们通过SPI将以太网帧(通过sk_buff-> data检索的字节数组)发送到ASIC,然后将其发送到电力线上。TCP不能用于自定义网络设备驱动程序

我们有这样的设置:

ARM委员会1 --SPI - >ASIC ---电源线--->ASIC --SPI - >ARM Board2

运行的Linux内核版本2.6.31

两个ARM板我们能够ping使用我们的司机相互ARM板(使用ping)。 我们可以在ARM板之间双向交换UDP数据包(使用iperf)。 但我们无法建立两个板之间的TCP连接(使用telnet/telnetd或iperf)。

似乎只有包含TCP的帧没有被TCP/IP层处理。情况会是这样吗?在将它传递给上层之前,我们是否正确地填充了sk_buff?

这里是其产生的驱动程序代码的适当部分,填充并传递的sk_buff到上层(U32 RX_DATA和U8 rx_len存储刚接收到的以太网帧):

skb1 = alloc_skb((rx_len + NET_IP_ALIGN), GFP_ATOMIC); 
skb_reserve(skb1, NET_IP_ALIGN); 
skb_put(skb1, rx_len); 
memcpy(skb1->data, rx_data, rx_len);    
skb1->protocol = eth_type_trans(skb1,gvspi_dev); 
skb_reset_network_header(skb1); 
skb_reset_transport_header(skb1); 

gvspi_dev->stats.rx_bytes += skb1->len; 
gvspi_dev->stats.rx_packets++; 

printk("Frame sent to TCP/IP layer..."); 

if (netif_rx_ni (skb1) != NET_RX_SUCCESS) { 
    kfree_skb (skb1); 
    gvspi_dev->stats.rx_dropped++;  
    return ERROR; 
} 

回答

0

所以我们能够找出问题 - RTFM分类问题。 我们已经分配了定制的以太网驱动器的MAC地址作为11:22:33:44:55:66,它当然是一个多播地址(见图here

此外,谁想要的详细信息: 看内核源程序的tcp_ipv4.c中的tcp_v4_rcv()的行号1615

每当我们使用多播MAC地址时,发送到此TCPv4接收函数的sk_buff从下层预置为PACKET_MULTICAST。 因此,此时sk_buff被拒绝,因为接收到的帧并没有按照TCP的要求专门指向我们的主机。组播只在UDP等无连接协议中有效。