1. f_eem
== eem_alloc_inst();
== gether_setup_default();
== gether_setup_name_default("usb");
== alloc_etherdev();
== alloc_etherdev_mqs();
== ether_setup(struct net_device *dev); //设置net_device 的参数mtu、len等
== net->netdev_ops = ð_netdev_ops;
1.1 module_param 的使用
// drivers/usb/gadget/function/u_ether.c
static unsigned int mtu_prealloc_databuf = 15000;
module_param(mtu_prealloc_databuf, uint, 0644);
MODULE_PARM_DESC(mtu_prealloc_databuf, "mtu >= will use prealloc buffer");
console:/ # cat /sys/module/u_ether/parameters/
disable_sg mtu_prealloc_databuf rx_prealloc_databuf_num
gso_segs prealloc_databuf_disable skb_timestamp_enable
gso_size prealloc_databuf_only
2. tcpdump
tcpdump -i eth2 //抓指定网口的包
2.1 包格式
数据包内容,包括Flags 标识符,seq 号,ack 号,win 窗口,数据长度 length.
//时分秒毫秒 发送方的ip地址+端口号 接收方的ip地址+端口号 Flags标识符 seq 号 ack 号 win窗口 数据长度length
21:26:49.013621 IP 172.20.20.1.15605 > 172.20.20.2.5920: Flags [P.], seq 49:97, ack 106048, win 4723, length 48
2.2 change mtu 抓包
(1)mtu 1500
12:42:06.898072 IP 192.168.1.10.45270 > 192.168.1.20.5201: Flags [.], seq 103178726:103180174, ack 1, win 502, options [nop,nop,TS val 157079759 ecr 1097442710], length 1448
// length = mtu - 52
[ 769.533238] net usb0: (rx_submit) size = 1536, truesize = 2432
// size = mtu + 36
(2)mtu 1000
12:45:24.028239 IP 192.168.1.10.45276 > 192.168.1.20.5201: Flags [.], seq 71538962:71539910, ack 1, win 502, options [nop,nop,TS val 157276883 ecr 1097639834], length 948
(3)mtu 15000
12:38:46.366106 IP 192.168.1.10.45318 > 192.168.1.20.5201: Flags [.], seq 115978110:115993058, ack 1, win 468, options [nop,nop,TS val 159515656 ecr 139947350], length 14948
[ 975.318177] net usb0: (rx_submit) size = 15036, truesize = 16640
(4)mtu 15300
12:47:41.546309 IP 192.168.1.10.45324 > 192.168.1.20.5201: Flags [.], seq 117677942:117693190, ack 1, win 477, options [nop,nop,TS val 160050814 ecr 140482515], length 15248
[ 1076.693443] net usb0: (rx_submit) size = 15336, truesize = 16640
(5)ping
13:10:00.299670 IP 192.168.1.20 > 192.168.1.10: ICMP echo reply, id 11511, seq 10, length 64
13:10:01.299121 IP 192.168.1.10 > 192.168.1.20: ICMP echo request, id 11511, seq 11, length 64
5. usb function - eem
5.1 ecm_alloc_inst and eem_alloc
alloc_inst 的调用:
== configfs_mkdir();
== function_make(struct config_group *group, const char *name);
== usb_get_function_instance();
== try_get_usb_function_instance(const char *name); // 从func_list 中找到fd
== fd->alloc_inst();
== ecm_alloc_inst();
alloc_func 的调用:
== config_usb_cfg_link();
== usb_get_function(struct usb_function_instance *fi);
== f = fi->fd->alloc_func(fi); //struct usb_function *f;
== eem_alloc(struct usb_function_instance *fi); //例子
static struct usb_function *eem_alloc(struct usb_function_instance *fi)
{
struct f_eem *eem;
struct f_eem_opts *opts;
eem->port.func.name = "cdc_eem";
/* descriptors are per-instance copies */
eem->port.func.bind = eem_bind; //struct usb_function func;
eem->port.func.unbind = eem_unbind;
eem->port.func.set_alt = eem_set_alt;
eem->port.func.setup = eem_setup;
eem->port.func.disable = eem_disable;
eem->port.func.free_func = eem_free;
eem->port.wrap = eem_wrap;
eem->port.unwrap = eem_unwrap;
eem->port.header_len = EEM_HLEN;
return &eem->port.func;
}
5.2 eem_bind
== gadget_dev_desc_UDC_store(); // \drivers\usb\gadget\configfs.c
== usb_gadget_probe_driver(struct usb_gadget_driver *driver) // \drivers\usb\gadget\udc\core.c
== udc_bind_to_driver(); //绑定usb_gadget_driver 与usb_udc
== driver->bind(udc->gadget, driver);
== configfs_composite_bind();
== usb_add_function(c, f); //添加function,执行function 的函数
== function->bind(config, function);
== eem_bind(struct usbnet *dev, struct usb_interface *intf);
5.3 start enum
主机开始枚举 USB设备。
5.3.1 eem_set_alt
设置配置:
== dwc3_thread_interrupt(); //中断产生(host发消息过来),调用回调函数
== dwc3_process_event_buf(); //处理中断事件buf(dwc3_event_buffer )
== dwc3_process_event_entry(); trace_dwc3_event(event->raw, dwc);
== dwc3_endpoint_interrupt(); //对端点处理的中断
== dwc3_ep0_interrupt(); //控制传输if (epnum == 0 || epnum == 1)
== dwc3_ep0_xfer_complete(); //event->endpoint_event = DWC3_DEPEVT_XFERCOMPLETE
== dwc3_ep0_inspect_setup(); //dwc->ep0state = EP0_SETUP_PHASE
//dwc3_ep0_std_request() == dwc3_ep0_set_config() 标准的USB请求
== dwc3_ep0_delegate_req(); //非标准的USB请求
== dwc->gadget_driver->setup(&dwc->gadget, ctrl);
== configfs_composite_setup();
== composite_setup(); //setup 包括获取描述符,配置,地址等操作
== set_config(cdev, ctrl, w_value); //ctrl->bRequest = USB_REQ_SET_CONFIGURATION
== f->set_alt(f, tmp, 0);
== eem_set_alt(struct usb_function *f, unsigned intf, unsigned alt);
5.3.2 eem_setup
== composite_setup();
== f->setup(f, ctrl);
== eem_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl);
5.3.3 eem_wrap
eem 私有的,开始传输数据。
== eth_start_xmit(struct sk_buff *skb, struct net_device *net);
== dev->wrap(dev->port_usb, skb);
== eem_wrap(struct gether *port, struct sk_buff *skb);
== eth_open(struct net_device *net);
== eth_start(struct eth_dev *dev, gfp_t gfp_flags);
== rx_fill(struct eth_dev *dev, gfp_t gfp_flags);
== rx_submit(struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags);
req->complete = rx_complete;
== rx_complete(struct usb_ep *ep, struct usb_request *req);
== dev->unwrap(dev->port_usb, skb, &dev->rx_frames);
== eem_unwrap();