int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); skb_queue_head_init(&dev->rx_frames); dev->net = net; strcpy(net->name, "usb%d"); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); netif_stop_queue(net); netif_carrier_off(net); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; } return status; }
/** * gether_setup_name - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * @netname: name for network device (for example, "usb") * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ struct eth_dev *gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], const char *netname) { struct eth_dev *dev; struct net_device *net; int status; net = alloc_etherdev(sizeof *dev); if (!net) return ERR_PTR(-ENOMEM); dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); skb_queue_head_init(&dev->rx_frames); /* network device setup */ dev->net = net; snprintf(net->name, sizeof(net->name), "%s%%d", netname); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); dev = ERR_PTR(status); } else { INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_carrier_off(net); } return dev; }
/** * gether_setup - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int __init gether_setup(u8 ethaddr[ETH_ALEN]) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); /* network device setup */ dev->net = net; strcpy(net->name, "ld%d"); if (get_ether_addr(dev_addr, net->dev_addr)) printk("using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) printk("using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_stop_queue(net); netif_carrier_off(net); // SET_NETDEV_DEV(net, &g->dev); status = register_netdev(net); if (status < 0) { printk("register_netdev failed, %d\n", status); free_netdev(net); } else { INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; } return status; }
int gether_set_host_addr(struct net_device *net, const char *host_addr) { struct eth_dev *dev; u8 new_addr[ETH_ALEN]; dev = netdev_priv(net); if (get_ether_addr(host_addr, new_addr)) return -EINVAL; memcpy(dev->host_mac, new_addr, ETH_ALEN); return 0; }
int sifproxyarp( int unit, uint32_t hisaddr) { int routes; /* * Get the hardware address of an interface on the same subnet * as our local address. */ memset(&arpmsg, 0, sizeof(arpmsg)); if (!get_ether_addr(hisaddr, &arpmsg.hwa)) { error("Cannot determine ethernet address for proxy ARP"); return 0; } if ((routes = socket(PF_ROUTE, SOCK_RAW, AF_INET)) < 0) { error("Couldn't add proxy arp entry: socket: %m"); return 0; } arpmsg.hdr.rtm_type = RTM_ADD; arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC; arpmsg.hdr.rtm_version = RTM_VERSION; arpmsg.hdr.rtm_seq = ++rtm_seq; arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY; arpmsg.hdr.rtm_inits = RTV_EXPIRE; arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp); arpmsg.dst.sin_family = AF_INET; arpmsg.dst.sin_addr.s_addr = hisaddr; arpmsg.dst.sin_other = SIN_PROXY; arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg + arpmsg.hwa.sdl_len; if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) { error("Couldn't add proxy arp entry: %m"); close(routes); return 0; } close(routes); arpmsg_valid = 1; proxy_arp_addr = hisaddr; return 1; }
int sifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; /* * Sometime in the 1.3 series kernels, the arp request added a device name. */ #include <linux/version.h> #if LINUX_VERSION_CODE < 66381 char arpreq_arp_dev[32]; #else #define arpreq_arp_dev arpreq.arp_dev #endif if (has_proxy_arp == 0) { memset (&arpreq, '\0', sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(his_adr, &arpreq.arp_ha, arpreq_arp_dev)) { syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); return 0; } SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); return 0; } } has_proxy_arp = 1; return 1; }
/* * sifproxyarp - Make a proxy ARP entry for the peer. */ int sifproxyarp( int unit, uint32_t hisaddr) { struct arpreq arpreq; struct { struct sockaddr_dl sdl; char space[128]; } dls; BZERO(&arpreq, sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ if (!get_ether_addr(hisaddr, &dls.sdl)) { error("Cannot determine ethernet address for proxy ARP"); return 0; } arpreq.arp_ha.sa_len = sizeof(struct sockaddr); arpreq.arp_ha.sa_family = AF_UNSPEC; BCOPY(LLADDR(&dls.sdl), arpreq.arp_ha.sa_data, dls.sdl.sdl_alen); SET_SA_FAMILY(arpreq.arp_pa, AF_INET); ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = hisaddr; arpreq.arp_flags = ATF_PERM | ATF_PUBL; if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) { error("Couldn't add proxy arp entry: %m"); return 0; } proxy_arp_addr = hisaddr; return 1; }
/** * gether_setup - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; #ifdef CONFIG_USB_ANDROID_VERIZON /* verizon requirement : mtu size fix to 1428 */ net->mtu = 1428; #endif dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); skb_queue_head_init(&dev->rx_frames); /* network device setup */ dev->net = net; strcpy(net->name, "usb%d"); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_stop_queue(net); netif_carrier_off(net); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { the_dev = dev; } return status; }
/** * gether_setup_name - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * @netname: name for network device (for example, "usb") * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], const char *netname) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); skb_queue_head_init(&dev->rx_frames); /* network device setup */ dev->net = net; snprintf(net->name, sizeof(net->name), "%s%%d", netname); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); #ifdef CONFIG_USB_ANDROID_SAMSUNG_COMPOSITE memcpy(dev->host_mac, ethaddr, ETH_ALEN); printk(KERN_DEBUG "usb: set unique host mac\n"); #else if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); #endif net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { the_dev = dev; /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_carrier_off(net); } return status; }
/** * gether_setup - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; pr_info("gether_setup \n"); net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); spin_lock_init(&dev->req_rx_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); dev->rx_workqueue = create_singlethread_workqueue("rx_ether_queue"); if (dev->rx_workqueue == NULL) { DBG(dev, "kevent %d rx_ether_queue creation fail once \n", ethaddr[ETH_ALEN]); } /* network device setup */ dev->net = net; strcpy(net->name, "usb%d"); #if 0 //We use the fixed host MAC address for USB logging. if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); #else dev_warn(&g->dev, "using fixed %s ethernet address\n", "self"); net->dev_addr [0] = 0x22; net->dev_addr [1] = 0x33; net->dev_addr [2] = 0x44; net->dev_addr [3] = 0x55; net->dev_addr [4] = 0x66; net->dev_addr [5] = 0x77; dev_warn(&g->dev, "using fixed %s ethernet address\n", "host"); dev->host_mac [0] = 0xaa; dev->host_mac [1] = 0xbb; dev->host_mac [2] = 0xcc; dev->host_mac [3] = 0xdd; dev->host_mac [4] = 0xee; dev->host_mac [5] = 0xff; #endif if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_stop_queue(net); netif_carrier_off(net); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; } return status; }
/**************************************************** * Function: init_mac * Description: Initialise the MAC. * * NOTE: Will be left on BANK0. * * Input: * NONE * * Return: * SUCCESS If completed * FAILURE If there was a problem ***************************************************/ RETURN_STATUS init_mac() { // // Initialise some stuff. // init_link(); frame_buffer_pos = 0; mac_header_pos = 0; // Set callback so that all received data comes back here. set_recv_data_callback(&recv_frame_bytes); // NOW MAC CHIP SETUP // // Start with bank0 registers. // // Set receive buffer; write_control_register(ERXSTL, (RX_START & 0xFF)); write_control_register(ERXSTH, (RX_START >> 8)); // Rx pointer write_control_register(ERXRDPTL, (RX_START & 0xFF)); write_control_register(ERXRDPTH, (RX_START >> 8)); // // Bank 1 looks complicated. // // KISS. No filters needed. // Everything else looks OK as defaults. // // Now onto bank 2. // write_control_register(ECON1, ECON1_BSEL1); write_control_register(MACON1, MACON1_TXPAUS | MACON1_RXPAUS | MACON1_MARXEN); write_control_register(MACON3, MACON3_PADCFG2 | MACON3_PADCFG1 | MACON3_PADCFG0 | MACON3_FRMLNEN | MACON3_TXCRCEN); write_control_register(MACON4, MACON4_DEFER); write_control_register(MABBIPG, MABBIPG_BBIPG4 | MABBIPG_BBIPG1); write_control_register(MAMXFLL, (FRAMELEN_MAX & 0xFF)); write_control_register(MAMXFLH, (FRAMELEN_MAX >> 8)); write_control_register(MAIPGL, (MACIPG_VAL & 0xFF)); write_control_register(MAIPGH, (MACIPG_VAL >> 8)); // // Bank 3 // write_control_register(ECON1, ECON1_BSEL0 | ECON1_BSEL1); /* Get our address and write to device */ uint8_t mac_addr[6]; get_ether_addr(&mac_addr); write_control_register(MAADR1, mac_addr[0]); write_control_register(MAADR2, mac_addr[1]); write_control_register(MAADR3, mac_addr[2]); write_control_register(MAADR4, mac_addr[3]); write_control_register(MAADR5, mac_addr[4]); write_control_register(MAADR6, mac_addr[5]); // Now init the PHY layer. // Alter via bank 2 write_control_register(ECON1, ECON1_BSEL1); // PHY is indirect through MIREGADR, MIWRL, MIWRH write_control_register(MIREGADR, PHCON2); write_control_register(MIWRL, (PHCON2_HDLDIS & 0xFF)); write_control_register(MIWRH, (PHCON2_HDLDIS >> 8)); // Now set up ECON1 properly (and leave on bank0) write_control_register(ECON1, ECON1_RXEN | ECON1_CSUMEN); // BUSY status now set. Write should take 10uS. // Easier during init just to wait a tiny while uint16_t waiting = add_timer(1, NULL); if(waiting != 0) { while(is_running(waiting) == TRUE); } return SUCCESS; }
/** * gether_setup - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int __init gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); /* network device setup */ dev->net = net; strcpy(net->name, "usb%d"); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->change_mtu = eth_change_mtu; net->hard_start_xmit = eth_start_xmit; net->open = eth_open; net->stop = eth_stop; /* watchdog_timeo, tx_timeout ... */ /* set_multicast_list */ SET_ETHTOOL_OPS(net, &ops); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_stop_queue(net); netif_carrier_off(net); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { DECLARE_MAC_BUF(tmp); INFO(dev, "MAC %s\n", print_mac(tmp, net->dev_addr)); INFO(dev, "HOST MAC %s\n", print_mac(tmp, dev->host_mac)); the_dev = dev; } return status; }
/* * Set an individual arp entry */ static int set(int argc, char **argv) { struct sockaddr_in *addr; struct sockaddr_in *dst; /* what are we looking for */ struct sockaddr_dl *sdl; struct rt_msghdr *rtm; struct ether_addr *ea; char *host = argv[0], *eaddr = argv[1]; struct sockaddr_dl sdl_m; argc -= 2; argv += 2; bzero(&sdl_m, sizeof(sdl_m)); sdl_m.sdl_len = sizeof(sdl_m); sdl_m.sdl_family = AF_LINK; dst = getaddr(host); if (dst == NULL) return (1); doing_proxy = flags = expire_time = 0; while (argc-- > 0) { if (strncmp(argv[0], "temp", 4) == 0) { struct timespec tp; int max_age; size_t len = sizeof(max_age); clock_gettime(CLOCK_MONOTONIC, &tp); if (sysctlbyname("net.link.ether.inet.max_age", &max_age, &len, NULL, 0) != 0) err(1, "sysctlbyname"); expire_time = tp.tv_sec + max_age; } else if (strncmp(argv[0], "pub", 3) == 0) { flags |= RTF_ANNOUNCE; doing_proxy = 1; if (argc && strncmp(argv[1], "only", 3) == 0) { /* * Compatibility: in pre FreeBSD 8 times * the "only" keyword used to mean that * an ARP entry should be announced, but * not installed into routing table. */ argc--; argv++; } } else if (strncmp(argv[0], "blackhole", 9) == 0) { if (flags & RTF_REJECT) { printf("Choose one of blackhole or reject, not both.\n"); } flags |= RTF_BLACKHOLE; } else if (strncmp(argv[0], "reject", 6) == 0) { if (flags & RTF_BLACKHOLE) { printf("Choose one of blackhole or reject, not both.\n"); } flags |= RTF_REJECT; } else if (strncmp(argv[0], "trail", 5) == 0) { /* XXX deprecated and undocumented feature */ printf("%s: Sending trailers is no longer supported\n", host); } argv++; } ea = (struct ether_addr *)LLADDR(&sdl_m); if (doing_proxy && !strcmp(eaddr, "auto")) { if (!get_ether_addr(dst->sin_addr.s_addr, ea)) { printf("no interface found for %s\n", inet_ntoa(dst->sin_addr)); return (1); } sdl_m.sdl_alen = ETHER_ADDR_LEN; } else { struct ether_addr *ea1 = ether_aton(eaddr); if (ea1 == NULL) { warnx("invalid Ethernet address '%s'", eaddr); return (1); } else { *ea = *ea1; sdl_m.sdl_alen = ETHER_ADDR_LEN; } } /* * In the case a proxy-arp entry is being added for * a remote end point, the RTF_ANNOUNCE flag in the * RTM_GET command is an indication to the kernel * routing code that the interface associated with * the prefix route covering the local end of the * PPP link should be returned, on which ARP applies. */ rtm = rtmsg(RTM_GET, dst, &sdl_m); if (rtm == NULL) { warn("%s", host); return (1); } addr = (struct sockaddr_in *)(rtm + 1); sdl = (struct sockaddr_dl *)(SA_SIZE(addr) + (char *)addr); if ((sdl->sdl_family != AF_LINK) || (rtm->rtm_flags & RTF_GATEWAY) || !valid_type(sdl->sdl_type)) { printf("cannot intuit interface index and type for %s\n", host); return (1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return (rtmsg(RTM_ADD, dst, &sdl_m) == NULL); }
/** * gether_setup_name - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * @netname: name for network device (for example, "usb") * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int gether_setup_name(struct usb_gadget *g, u8 ethaddr[ETH_ALEN], const char *netname) { struct eth_dev *dev; struct net_device *net; int status; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); //init_waitqueue_head(&dev->usb_tx_buf_wq); skb_queue_head_init(&dev->rx_frames); /* network device setup */ dev->net = net; snprintf(net->name, sizeof(net->name), "%s%%d", netname); if (get_ether_addr(dev_addr, net->dev_addr)) dev_warn(&g->dev, "using random %s ethernet address\n", "self"); if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); dev->usb_tx_buf_flag = 0; dev->usb_tx_buf = kzalloc(MAX_USB_TX_BUF_SIZE, GFP_ATOMIC); if (dev->usb_tx_buf != NULL) printk("%s: kzalloc dev->usb_tx_buf = %p.\n", __FUNCTION__, dev->usb_tx_buf); else printk("%s: kzalloc failed.\n", __FUNCTION__); the_dev = dev; /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_carrier_off(net); } return status; }
/** * gether_setup - initialize one ethernet-over-usb link * @g: gadget to associated with these links * @ethaddr: NULL, or a buffer in which the ethernet address of the * host side of the link is recorded * Context: may sleep * * This sets up the single network link that may be exported by a * gadget driver using this framework. The link layer addresses are * set up using module parameters. * * Returns negative errno, or zero on success */ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) { struct eth_dev *dev; struct net_device *net; int status; int gpio_171, gpio_172, val; if (the_dev) return -EBUSY; net = alloc_etherdev(sizeof *dev); if (!net) return -ENOMEM; dev = netdev_priv(net); spin_lock_init(&dev->lock); spin_lock_init(&dev->req_lock); INIT_WORK(&dev->work, eth_work); INIT_LIST_HEAD(&dev->tx_reqs); INIT_LIST_HEAD(&dev->rx_reqs); skb_queue_head_init(&dev->rx_frames); /* network device setup */ dev->net = net; strcpy(net->name, "usb%d"); if (get_ether_addr(dev_addr, net->dev_addr)){ dev_warn(&g->dev, "using %s ethernet address\n", "Quanta defined"); // "using random %s ethernet address\n", "self"); net->dev_addr[0] = 0x00; net->dev_addr[1] = 0x02; net->dev_addr[2] = 0x00; net->dev_addr[3] = 0x00; net->dev_addr[4] = 0x00; gpio_171 = gpio_get_value(171); gpio_172 = gpio_get_value(172); //gpio_171 = 1; //gpio_172 = 1; val = (gpio_171 << 1) + gpio_172; printk("< Quanta_diagnostic > gpio_171 = %d gpio_172 = %d val = %d\n", gpio_171, gpio_172, val ); switch (val) { case 0: net->dev_addr[5] = 0x01; break; case 1: net->dev_addr[5] = 0x03; break; case 2: net->dev_addr[5] = 0x07; break; case 3: net->dev_addr[5] = 0x09; break; default: printk("default\n"); break; //random_ether_addr(dev_addr); } printk("< Quanta Diagnostic > set dev_addr done !\n"); } if (get_ether_addr(host_addr, dev->host_mac)) dev_warn(&g->dev, "using random %s ethernet address\n", "host"); if (ethaddr) memcpy(ethaddr, dev->host_mac, ETH_ALEN); net->netdev_ops = ð_netdev_ops; SET_ETHTOOL_OPS(net, &ops); /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ netif_stop_queue(net); netif_carrier_off(net); dev->gadget = g; SET_NETDEV_DEV(net, &g->dev); SET_NETDEV_DEVTYPE(net, &gadget_type); status = register_netdev(net); if (status < 0) { dev_dbg(&g->dev, "register_netdev failed, %d\n", status); free_netdev(net); } else { INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); the_dev = dev; } return status; }
/* * Set an individual arp entry */ int set(int argc, char **argv) { struct hostent *hp; struct sockaddr_inarp *addr = &sin_m; struct sockaddr_dl *sdl; struct rt_msghdr *rtm = &(m_rtmsg.m_rtm); struct ether_addr *ea; char *host = argv[0], *eaddr = argv[1]; getsocket(); argc -= 2; argv += 2; sdl_m = blank_sdl; sin_m = blank_sin; addr->sin_addr.s_addr = inet_addr(host); if (addr->sin_addr.s_addr == INADDR_NONE) { if (!(hp = gethostbyname(host))) { warnx("%s: %s", host, hstrerror(h_errno)); return(1); } bcopy((char *)hp->h_addr, (char *)&addr->sin_addr, sizeof(addr->sin_addr)); } doing_proxy = flags = proxy_only = expire_time = 0; while (argc-- > 0) { if (strncmp(argv[0], "temp", 4) == 0) { struct timeval tv; gettimeofday(&tv, 0); expire_time = tv.tv_sec + 20 * 60; } else if (strncmp(argv[0], "pub", 3) == 0) { flags |= RTF_ANNOUNCE; doing_proxy = 1; if (argc && strncmp(argv[1], "only", 3) == 0) { proxy_only = 1; sin_m.sin_other = SIN_PROXY; argc--; argv++; } } else if (strncmp(argv[0], "trail", 5) == 0) { printf("%s: Sending trailers is no longer supported\n", host); } argv++; } ea = (struct ether_addr *)LLADDR(&sdl_m); if (doing_proxy && !strcmp(eaddr, "auto")) { if (!get_ether_addr(addr->sin_addr.s_addr, ea)) { printf("no interface found for %s\n", inet_ntoa(addr->sin_addr)); return(1); } sdl_m.sdl_alen = ETHER_ADDR_LEN; } else { if (my_ether_aton(eaddr, ea) == 0) sdl_m.sdl_alen = ETHER_ADDR_LEN; } tryagain: if (rtmsg(RTM_GET) < 0) { warn("%s", host); return(1); } addr = (struct sockaddr_inarp *)(rtm + 1); sdl = (struct sockaddr_dl *)(ROUNDUP(addr->sin_len) + (char *)addr); if (addr->sin_addr.s_addr == sin_m.sin_addr.s_addr) { if (sdl->sdl_family == AF_LINK && (rtm->rtm_flags & RTF_LLINFO) && !(rtm->rtm_flags & RTF_GATEWAY)) switch (sdl->sdl_type) { case IFT_ETHER: case IFT_FDDI: case IFT_ISO88023: case IFT_ISO88024: case IFT_ISO88025: case IFT_L2VLAN: case IFT_CARP: goto overwrite; } if (doing_proxy == 0) { printf("set: can only proxy for %s\n", host); return(1); } if (sin_m.sin_other & SIN_PROXY) { printf("set: proxy entry exists for non 802 device\n"); return(1); } sin_m.sin_other = SIN_PROXY; proxy_only = 1; goto tryagain; } overwrite: if (sdl->sdl_family != AF_LINK) { printf("cannot intuit interface index and type for %s\n", host); return(1); } sdl_m.sdl_type = sdl->sdl_type; sdl_m.sdl_index = sdl->sdl_index; return(rtmsg(RTM_ADD)); }