static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct ifinfomsg *ifm = NLMSG_DATA(nlh); struct rtattr **ida = arg; struct net_device *dev; int err, send_addr_notify = 0; if (ifm->ifi_index >= 0) dev = dev_get_by_index(ifm->ifi_index); else if (ida[IFLA_IFNAME - 1]) { char ifname[IFNAMSIZ]; if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], IFNAMSIZ) >= IFNAMSIZ) return -EINVAL; dev = dev_get_by_name(ifname); } else return -EINVAL; if (!dev) return -ENODEV; err = -EINVAL; if (ifm->ifi_flags) dev_change_flags(dev, ifm->ifi_flags); if (ida[IFLA_MAP - 1]) { struct rtnl_link_ifmap *u_map; struct ifmap k_map; if (!dev->set_config) { err = -EOPNOTSUPP; goto out; } if (!netif_device_present(dev)) { err = -ENODEV; goto out; } if (ida[IFLA_MAP - 1]->rta_len != RTA_LENGTH(sizeof(*u_map))) goto out; u_map = RTA_DATA(ida[IFLA_MAP - 1]); k_map.mem_start = (unsigned long) u_map->mem_start; k_map.mem_end = (unsigned long) u_map->mem_end; k_map.base_addr = (unsigned short) u_map->base_addr; k_map.irq = (unsigned char) u_map->irq; k_map.dma = (unsigned char) u_map->dma; k_map.port = (unsigned char) u_map->port; err = dev->set_config(dev, &k_map); if (err) goto out; } if (ida[IFLA_ADDRESS - 1]) { if (!dev->set_mac_address) { err = -EOPNOTSUPP; goto out; } if (!netif_device_present(dev)) { err = -ENODEV; goto out; } if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) goto out; err = dev->set_mac_address(dev, RTA_DATA(ida[IFLA_ADDRESS - 1])); if (err) goto out; send_addr_notify = 1; } if (ida[IFLA_BROADCAST - 1]) { if (ida[IFLA_BROADCAST - 1]->rta_len != RTA_LENGTH(dev->addr_len)) goto out; memcpy(dev->broadcast, RTA_DATA(ida[IFLA_BROADCAST - 1]), dev->addr_len); send_addr_notify = 1; } if (ida[IFLA_MTU - 1]) { if (ida[IFLA_MTU - 1]->rta_len != RTA_LENGTH(sizeof(u32))) goto out; err = dev_set_mtu(dev, *((u32 *) RTA_DATA(ida[IFLA_MTU - 1]))); if (err) goto out; } if (ida[IFLA_TXQLEN - 1]) { if (ida[IFLA_TXQLEN - 1]->rta_len != RTA_LENGTH(sizeof(u32))) goto out; dev->tx_queue_len = *((u32 *) RTA_DATA(ida[IFLA_TXQLEN - 1])); } if (ida[IFLA_WEIGHT - 1]) { if (ida[IFLA_WEIGHT - 1]->rta_len != RTA_LENGTH(sizeof(u32))) goto out; dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); } if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { char ifname[IFNAMSIZ]; if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], IFNAMSIZ) >= IFNAMSIZ) goto out; err = dev_change_name(dev, ifname); if (err) goto out; } err = 0; out: if (send_addr_notify) call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); dev_put(dev); return err; }
static int ixgbe_dcb_gperm_hwaddr(struct sk_buff *skb, struct genl_info *info) { void *data; struct sk_buff *dcb_skb = NULL; struct nlattr *tb[IXGBE_DCB_PERM_HW_A_MAX + 1], *nest; struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; struct ixgbe_hw *hw = NULL; int ret = -ENOMEM; int i; if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PERM_HWADDR]) return -EINVAL; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) return -EINVAL; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err_out; else adapter = netdev_priv(netdev); hw = &adapter->hw; ret = nla_parse_nested(tb, IXGBE_DCB_PERM_HW_A_MAX, info->attrs[DCB_A_PERM_HWADDR], dcb_perm_hwaddr_nest); if (ret) goto err; dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!dcb_skb) goto err; data = genlmsg_put_reply(dcb_skb, info, &dcb_family, 0, DCB_C_GPERM_HWADDR); if (!data) goto err; nest = nla_nest_start(dcb_skb, DCB_A_PERM_HWADDR); if (!nest) goto err; for (i = 0; i < netdev->addr_len; i++) { if (!tb[i+PERM_HW_A_0] && !tb[PERM_HW_A_ALL]) goto err; ret = nla_put_u8(dcb_skb, DCB_A_PERM_HWADDR, hw->mac.perm_addr[i]); if (ret) { nla_nest_cancel(dcb_skb, nest); goto err; } } nla_nest_end(dcb_skb, nest); genlmsg_end(dcb_skb, data); ret = genlmsg_reply(dcb_skb, info); if (ret) goto err; dev_put(netdev); return 0; err: DPRINTK(DRV, ERR, "Error in get permanent hwaddr.\n"); kfree(dcb_skb); err_out: dev_put(netdev); return ret; }
static int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb) { struct dump_phy_data data = { .cb = cb, .skb = skb, .s_idx = cb->args[0], .idx = 0, }; pr_debug("%s\n", __func__); wpan_phy_for_each(ieee802154_dump_phy_iter, &data); cb->args[0] = data.idx; return skb->len; } static int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; struct wpan_phy *phy; const char *name; const char *devname; int rc = -ENOBUFS; struct net_device *dev; int type = __IEEE802154_DEV_INVALID; pr_debug("%s\n", __func__); if (!info->attrs[IEEE802154_ATTR_PHY_NAME]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ if (info->attrs[IEEE802154_ATTR_DEV_NAME]) { devname = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]); if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ } else { devname = "wpan%d"; } if (strlen(devname) >= IFNAMSIZ) return -ENAMETOOLONG; phy = wpan_phy_find(name); if (!phy) return -ENODEV; msg = ieee802154_nl_new_reply(info, 0, IEEE802154_ADD_IFACE); if (!msg) goto out_dev; if (!phy->add_iface) { rc = -EINVAL; goto nla_put_failure; } if (info->attrs[IEEE802154_ATTR_HW_ADDR] && nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) != IEEE802154_ADDR_LEN) { rc = -EINVAL; goto nla_put_failure; } if (info->attrs[IEEE802154_ATTR_DEV_TYPE]) { type = nla_get_u8(info->attrs[IEEE802154_ATTR_DEV_TYPE]); if (type >= __IEEE802154_DEV_MAX) { rc = -EINVAL; goto nla_put_failure; } } dev = phy->add_iface(phy, devname, type); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure; } if (info->attrs[IEEE802154_ATTR_HW_ADDR]) { struct sockaddr addr; addr.sa_family = ARPHRD_IEEE802154; nla_memcpy(&addr.sa_data, info->attrs[IEEE802154_ATTR_HW_ADDR], IEEE802154_ADDR_LEN); /* * strangely enough, some callbacks (inetdev_event) from * dev_set_mac_address require RTNL_LOCK */ rtnl_lock(); rc = dev_set_mac_address(dev, &addr); rtnl_unlock(); if (rc) goto dev_unregister; } if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) goto nla_put_failure; dev_put(dev); wpan_phy_put(phy); return ieee802154_nl_reply(msg, info); dev_unregister: rtnl_lock(); /* del_iface must be called with RTNL lock */ phy->del_iface(phy, dev); dev_put(dev); rtnl_unlock(); nla_put_failure: nlmsg_free(msg); out_dev: wpan_phy_put(phy); return rc; } static int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; struct wpan_phy *phy; const char *name; int rc; struct net_device *dev; pr_debug("%s\n", __func__); if (!info->attrs[IEEE802154_ATTR_DEV_NAME]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]); if (name[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* name should be null-terminated */ dev = dev_get_by_name(genl_info_net(info), name); if (!dev) return -ENODEV; phy = ieee802154_mlme_ops(dev)->get_phy(dev); BUG_ON(!phy); rc = -EINVAL; /* phy name is optional, but should be checked if it's given */ if (info->attrs[IEEE802154_ATTR_PHY_NAME]) { struct wpan_phy *phy2; const char *pname = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); if (pname[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') /* name should be null-terminated */ goto out_dev; phy2 = wpan_phy_find(pname); if (!phy2) goto out_dev; if (phy != phy2) { wpan_phy_put(phy2); goto out_dev; } } rc = -ENOBUFS; msg = ieee802154_nl_new_reply(info, 0, IEEE802154_DEL_IFACE); if (!msg) goto out_dev; if (!phy->del_iface) { rc = -EINVAL; goto nla_put_failure; } rtnl_lock(); phy->del_iface(phy, dev); /* We don't have device anymore */ dev_put(dev); dev = NULL; rtnl_unlock(); if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, name)) goto nla_put_failure; wpan_phy_put(phy); return ieee802154_nl_reply(msg, info); nla_put_failure: nlmsg_free(msg); out_dev: wpan_phy_put(phy); if (dev) dev_put(dev); return rc; } static struct genl_ops ieee802154_phy_ops[] = { IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy, ieee802154_dump_phy), IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface), IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface), }; /* * No need to unregister as family unregistration will do it. */ int nl802154_phy_register(void) { int i; int rc; for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) { rc = genl_register_ops(&nl802154_family, &ieee802154_phy_ops[i]); if (rc) return rc; } return 0; }
static ssize_t schar_write_3(struct file *file, const char *buf, size_t count, loff_t *offset) { // struct sock *sk; // char *sbuf; // char *pnt2; // unsigned char *addr; int len; int err; // int i; static struct net_device *dev; static struct sk_buff *skb; static unsigned short proto=0; // printk(KERN_INFO " length %d \n",count); // sbuf=kmalloc(9000,GFP_KERNEL); len=count; dev=dev_get_by_name("eth3"); err=-ENODEV; if (dev == NULL) goto out_unlock; /* * You may not queue a frame bigger than the mtu. This is the lowest level * raw protocol and you must do your own fragmentation at this level. */ err = -EMSGSIZE; if(len>dev->mtu+dev->hard_header_len) goto out_unlock; err = -ENOBUFS; // skb = sock_wmalloc(sk, len+dev->hard_header_len+15, 0, GFP_KERNEL); skb=dev_alloc_skb(len+dev->hard_header_len+15); /* * If the write buffer is full, then tough. At this level the user gets to * deal with the problem - do your own algorithmic backoffs. That's far * more flexible. */ if (skb == NULL) goto out_unlock; /* * Fill it in */ /* FIXME: Save some space for broken drivers that write a * hard header at transmission time by themselves. PPP is the * notable one here. This should really be fixed at the driver level. */ skb_reserve(skb,(dev->hard_header_len+15)&~15); skb->nh.raw = skb->data; proto=htons(ETH_P_ALL); /* if (dev->hard_header) { int res; err = -EINVAL; addr=NULL; res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); skb->tail = skb->data; skb->len = 0; } */ skb->tail = skb->data; skb->len = 0; /* Try to align data part correctly */ /* if (dev->hard_header) { skb->data -= dev->hard_header_len; skb->tail -= dev->hard_header_len; } */ // printk(KERN_INFO " header length %d \n",dev->hard_header_len); /* Returns -EFAULT on error */ // err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); err = copy_from_user(skb_put(skb,len),buf, count); // err = memcpy_fromio(skb_put(skb,len),sbuf,len); // printk(KERN_INFO " lsd: len count %d %d %02x \n",len,count,*(skb->data+98)&0xff); skb->protocol = htons(ETH_P_ALL); skb->dev = dev; skb->priority = 0; // skb->pkt_type=PACKET_MR_PROMISC; skb->ip_summed=CHECKSUM_UNNECESSARY; if (err) goto out_free; err = -ENETDOWN; if (!(dev->flags & IFF_UP)) goto out_free; /* * Now send it */ dev_queue_xmit(skb); dev_put(dev); // printk(KERN_INFO " lsd: len count %d %d %02x \n",len,count,*(skb->data+98)&0xff); // kfree(sbuf); proc_tpackets_3=proc_tpackets_3+1; proc_tbytesL_3=proc_tbytesL_3+len; if(proc_tbytesL_3>1000000000){ proc_tbytesL_3=proc_tbytesL_3-1000000000; proc_tbytesH_3=proc_tbytesH_3+1; } return count; out_free: kfree_skb(skb); out_unlock: // if (dev)dev_put(dev); // kfree(sbuf); return -EFAULT; }
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { int retval = -EIO; char local[12] = { 0 }; struct net_device *netdev = NULL; PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode; int wait_cnt = 0; down(&wr_mtx); if (count <= 0) { WIFI_ERR_FUNC("WIFI_write invalid param\n"); goto done; } if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { local[11] = 0; WIFI_INFO_FUNC("WIFI_write %s\n", local); if (local[0] == '0') { /* TODO */ /* Configure the EINT pin to GPIO mode. */ if (powered == 0) { WIFI_INFO_FUNC("WIFI is already power off!\n"); retval = count; wlan_mode = WLAN_MODE_HALT; goto done; } netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); if (netdev == NULL) { WIFI_ERR_FUNC("Fail to get wlan0 net device\n"); } else { p2pmode.u4Enable = 0; p2pmode.u4Mode = 0; if (pf_set_p2p_mode) { if (pf_set_p2p_mode(netdev, p2pmode) != 0) { WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); } else { WIFI_INFO_FUNC("Turn off p2p/ap mode"); wlan_mode = WLAN_MODE_HALT; } } dev_put(netdev); netdev = NULL; } if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); } else { WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); powered = 0; retval = count; wlan_mode = WLAN_MODE_HALT; } } else if (local[0] == '1') { /* TODO */ /* Disable EINT(external interrupt), and set the GPIO to EINT mode. */ if (powered == 1) { WIFI_INFO_FUNC("WIFI is already power on!\n"); retval = count; goto done; } if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); } else { powered = 1; retval = count; WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); wlan_mode = WLAN_MODE_HALT; } } else if (local[0] == 'D') { int k = 0; /* * 0: no debug * 1: common debug output * 2: more detials * 3: verbose */ switch (local[1]) { case '0': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = 0; } if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; case '1': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; } wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO); wlan_dbg_level[DBG_INTR_IDX] = 0; wlan_dbg_level[DBG_MEM_IDX] = 0; if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; case '2': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO; } wlan_dbg_level[DBG_INTR_IDX] = 0; wlan_dbg_level[DBG_MEM_IDX] = 0; if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; case '3': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = DBG_CLASS_ERROR | DBG_CLASS_WARN | DBG_CLASS_STATE | DBG_CLASS_EVENT | DBG_CLASS_TRACE | DBG_CLASS_INFO | DBG_CLASS_LOUD; } if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; default: break; } } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { if (powered == 0) { /* If WIFI is off, turn on WIFI first */ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); goto done; } else { powered = 1; WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); wlan_mode = WLAN_MODE_HALT; } } if (pf_set_p2p_mode == NULL) { WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); goto done; } netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); while (netdev == NULL && wait_cnt < 10) { WIFI_ERR_FUNC("Fail to get wlan0 net device, sleep 300ms\n"); msleep(300); wait_cnt++; netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); } if (wait_cnt >= 10) { WIFI_ERR_FUNC("Get wlan0 net device timeout\n"); goto done; } if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))) { p2pmode.u4Enable = 0; p2pmode.u4Mode = 0; if (pf_set_p2p_mode(netdev, p2pmode) != 0) { WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); goto done; } } if (local[0] == 'S' || local[0] == 'P') { p2pmode.u4Enable = 1; p2pmode.u4Mode = 0; if (pf_set_p2p_mode(netdev, p2pmode) != 0) { WIFI_ERR_FUNC("Set wlan mode fail\n"); } else { WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); wlan_mode = WLAN_MODE_STA_P2P; retval = count; } } else if (local[0] == 'A') { p2pmode.u4Enable = 1; p2pmode.u4Mode = 1; if (pf_set_p2p_mode(netdev, p2pmode) != 0) { WIFI_ERR_FUNC("Set wlan mode fail\n"); } else { WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); wlan_mode = WLAN_MODE_AP; retval = count; } } dev_put(netdev); netdev = NULL; } } done: if (netdev != NULL) { dev_put(netdev); } up(&wr_mtx); return (retval); }
/***************************************************************************** Prototype : PreIP_send_frame Description : Build a Frame and send it out by defined interface (eg. eth0) Input : None Output : None Return Value : Calls : Called By : *****************************************************************************/ A_BOOL PreIP_send_frame(FramePreIpAll_t *preip_all) { u8 *pbuf = NULL; FrameSAPHead_t* psap; u32 tmp32; u16 tmp16; struct sk_buff * skb = NULL; struct net_device *dev; u8 dstmac[6]={0xff,0xff,0xff,0xff,0xff,0xff}; u8 srcmac[6]={0xff,0xff,0xff,0xff,0xff,0xff}; #ifdef PRE_IP_DEBUG printk("PreIP_DiscoveryResquest: in\n"); #endif dev = dev_get_by_name(&init_net, PREIP_NET_DEVICE_NAME); if(dev == NULL) { printk("%s: don't find device %s!\n", __func__, PREIP_NET_DEVICE_NAME); return FALSE; } if ((NULL == dstmac)||(NULL == srcmac)) return FALSE; skb = alloc_skb(FRAME_SAP_OCTETS + FRAME_PREIP_OCTETS + LL_RESERVED_SPACE(dev) + sizeof(FramePreIpAll_t), GFP_ATOMIC); if (skb == NULL) { printk("alloc_skb fail\n"); return FALSE; } skb_reserve(skb, LL_RESERVED_SPACE(dev)); pbuf = skb_put(skb,(FRAME_SAP_OCTETS+FRAME_PREIP_OCTETS+sizeof(FramePreIpAll_t))); skb->dev = dev; skb->protocol = htons(ETH_P_802_3); /* srcmac is eth0 mac address*/ memcpy(srcmac, dev->dev_addr, 6); /* build Ethernet header*/ if (dev_hard_header(skb,dev,ETH_P_802_3, dstmac, srcmac, skb->len) < 0) { printk("%s: dev_hard_header error\n", __func__); kfree_skb(skb); return FALSE; } /* build LLC*/ psap = (FrameSAPHead_t*)pbuf; psap->ssap = PREIP_SSAP; psap->dsap = PREIP_DSAP; psap->cmd = PREIP_SAPCMD; psap->vendorid[0] = PREIP_PRIV_ID1; psap->vendorid[1] = PREIP_PRIV_ID2; psap->vendorid[2] = PREIP_PRIV_ID3; psap->protocol = htons(PREIP_SAPPROTOCOL); memcpy(pbuf + FRAME_SAP_OCTETS, preip_all, sizeof(FramePreIpAll_t)); #ifdef PRE_IP_DEBUG printk("PreIP_Send Frame: skb->len=%d\n", skb->len); #endif /* send this frame out */ dev_queue_xmit(skb); return TRUE; }
static int l2tp_eth_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg) { struct net_device *dev; char name[IFNAMSIZ]; struct l2tp_tunnel *tunnel; struct l2tp_session *session; struct l2tp_eth *priv; struct l2tp_eth_sess *spriv; int rc; struct l2tp_eth_net *pn; tunnel = l2tp_tunnel_find(net, tunnel_id); if (!tunnel) { rc = -ENODEV; goto out; } session = l2tp_session_find(net, tunnel, session_id); if (session) { rc = -EEXIST; goto out; } if (cfg->ifname) { dev = dev_get_by_name(net, cfg->ifname); if (dev) { dev_put(dev); rc = -EEXIST; goto out; } strlcpy(name, cfg->ifname, IFNAMSIZ); } else strcpy(name, L2TP_ETH_DEV_NAME); session = l2tp_session_create(sizeof(*spriv), tunnel, session_id, peer_session_id, cfg); if (!session) { rc = -ENOMEM; goto out; } dev = alloc_netdev(sizeof(*priv), name, NET_NAME_UNKNOWN, l2tp_eth_dev_setup); if (!dev) { rc = -ENOMEM; goto out_del_session; } dev_net_set(dev, net); if (session->mtu == 0) session->mtu = dev->mtu - session->hdr_len; dev->mtu = session->mtu; dev->needed_headroom += session->hdr_len; priv = netdev_priv(dev); priv->dev = dev; priv->session = session; INIT_LIST_HEAD(&priv->list); priv->tunnel_sock = tunnel->sock; session->recv_skb = l2tp_eth_dev_recv; session->session_close = l2tp_eth_delete; #if defined(CONFIG_L2TP_DEBUGFS) || defined(CONFIG_L2TP_DEBUGFS_MODULE) session->show = l2tp_eth_show; #endif spriv = l2tp_session_priv(session); spriv->dev = dev; rc = register_netdev(dev); if (rc < 0) goto out_del_dev; __module_get(THIS_MODULE); /* Must be done after register_netdev() */ strlcpy(session->ifname, dev->name, IFNAMSIZ); dev_hold(dev); pn = l2tp_eth_pernet(dev_net(dev)); spin_lock(&pn->l2tp_eth_lock); list_add(&priv->list, &pn->l2tp_eth_dev_list); spin_unlock(&pn->l2tp_eth_lock); return 0; out_del_dev: free_netdev(dev); spriv->dev = NULL; out_del_session: l2tp_session_delete(session); out: return rc; }
static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { struct net *net = sock_net(skb->sk); struct net_device *netdev; struct dcbmsg *dcb = (struct dcbmsg *)NLMSG_DATA(nlh); struct nlattr *tb[DCB_ATTR_MAX + 1]; u32 pid = skb ? NETLINK_CB(skb).pid : 0; int ret = -EINVAL; if (net != &init_net) return -EINVAL; ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, dcbnl_rtnl_policy); if (ret < 0) return ret; if (!tb[DCB_ATTR_IFNAME]) return -EINVAL; netdev = dev_get_by_name(&init_net, nla_data(tb[DCB_ATTR_IFNAME])); if (!netdev) return -EINVAL; if (!netdev->dcbnl_ops) goto errout; switch (dcb->cmd) { case DCB_CMD_GSTATE: ret = dcbnl_getstate(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PFC_GCFG: ret = dcbnl_getpfccfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_GPERM_HWADDR: ret = dcbnl_getperm_hwaddr(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PGTX_GCFG: ret = dcbnl_pgtx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PGRX_GCFG: ret = dcbnl_pgrx_getcfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_BCN_GCFG: ret = dcbnl_bcn_getcfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_SSTATE: ret = dcbnl_setstate(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PFC_SCFG: ret = dcbnl_setpfccfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_SET_ALL: ret = dcbnl_setall(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PGTX_SCFG: ret = dcbnl_pgtx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PGRX_SCFG: ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_GCAP: ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_GNUMTCS: ret = dcbnl_getnumtcs(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_SNUMTCS: ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PFC_GSTATE: ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_PFC_SSTATE: ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_BCN_SCFG: ret = dcbnl_bcn_setcfg(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_GAPP: ret = dcbnl_getapp(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; case DCB_CMD_SAPP: ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, nlh->nlmsg_flags); goto out; default: goto errout; } errout: ret = -EINVAL; out: dev_put(netdev); return ret; }
int sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk=sock->sk; struct sk_filter *filter; int val; int valbool; struct linger ling; int ret = 0; /* * Options without arguments */ #ifdef SO_DONTLINGER /* Compatibility item... */ if (optname == SO_DONTLINGER) { lock_sock(sk); sock_reset_flag(sk, SOCK_LINGER); release_sock(sk); return 0; } #endif if(optlen<sizeof(int)) return(-EINVAL); if (get_user(val, (int __user *)optval)) return -EFAULT; valbool = val?1:0; lock_sock(sk); switch(optname) { case SO_DEBUG: if(val && !capable(CAP_NET_ADMIN)) { ret = -EACCES; } else if (valbool) sock_set_flag(sk, SOCK_DBG); else sock_reset_flag(sk, SOCK_DBG); break; case SO_REUSEADDR: sk->sk_reuse = valbool; break; case SO_TYPE: case SO_ERROR: ret = -ENOPROTOOPT; break; case SO_DONTROUTE: if (valbool) sock_set_flag(sk, SOCK_LOCALROUTE); else sock_reset_flag(sk, SOCK_LOCALROUTE); break; case SO_BROADCAST: sock_valbool_flag(sk, SOCK_BROADCAST, valbool); break; case SO_SNDBUF: /* Don't error on this BSD doesn't and if you think about it this is right. Otherwise apps have to play 'guess the biggest size' games. RCVBUF/SNDBUF are treated in BSD as hints */ if (val > sysctl_wmem_max) val = sysctl_wmem_max; set_sndbuf: sk->sk_userlocks |= SOCK_SNDBUF_LOCK; if ((val * 2) < SOCK_MIN_SNDBUF) sk->sk_sndbuf = SOCK_MIN_SNDBUF; else sk->sk_sndbuf = val * 2; /* * Wake up sending tasks if we * upped the value. */ sk->sk_write_space(sk); break; case SO_SNDBUFFORCE: if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } goto set_sndbuf; case SO_RCVBUF: /* Don't error on this BSD doesn't and if you think about it this is right. Otherwise apps have to play 'guess the biggest size' games. RCVBUF/SNDBUF are treated in BSD as hints */ if (val > sysctl_rmem_max) val = sysctl_rmem_max; set_rcvbuf: sk->sk_userlocks |= SOCK_RCVBUF_LOCK; /* * We double it on the way in to account for * "struct sk_buff" etc. overhead. Applications * assume that the SO_RCVBUF setting they make will * allow that much actual data to be received on that * socket. * * Applications are unaware that "struct sk_buff" and * other overheads allocate from the receive buffer * during socket buffer allocation. * * And after considering the possible alternatives, * returning the value we actually used in getsockopt * is the most desirable behavior. */ if ((val * 2) < SOCK_MIN_RCVBUF) sk->sk_rcvbuf = SOCK_MIN_RCVBUF; else sk->sk_rcvbuf = val * 2; break; case SO_RCVBUFFORCE: if (!capable(CAP_NET_ADMIN)) { ret = -EPERM; break; } goto set_rcvbuf; case SO_KEEPALIVE: #ifdef CONFIG_INET if (sk->sk_protocol == IPPROTO_TCP) tcp_set_keepalive(sk, valbool); #endif sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool); break; case SO_OOBINLINE: sock_valbool_flag(sk, SOCK_URGINLINE, valbool); break; case SO_NO_CHECK: sk->sk_no_check = valbool; break; case SO_PRIORITY: if ((val >= 0 && val <= 6) || capable(CAP_NET_ADMIN)) sk->sk_priority = val; else ret = -EPERM; break; case SO_LINGER: if(optlen<sizeof(ling)) { ret = -EINVAL; /* 1003.1g */ break; } if (copy_from_user(&ling,optval,sizeof(ling))) { ret = -EFAULT; break; } if (!ling.l_onoff) sock_reset_flag(sk, SOCK_LINGER); else { #if (BITS_PER_LONG == 32) if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; else #endif sk->sk_lingertime = (unsigned int)ling.l_linger * HZ; sock_set_flag(sk, SOCK_LINGER); } break; case SO_BSDCOMPAT: sock_warn_obsolete_bsdism("setsockopt"); break; case SO_PASSCRED: if (valbool) set_bit(SOCK_PASSCRED, &sock->flags); else clear_bit(SOCK_PASSCRED, &sock->flags); break; case SO_TIMESTAMP: if (valbool) { sock_set_flag(sk, SOCK_RCVTSTAMP); sock_enable_timestamp(sk); } else sock_reset_flag(sk, SOCK_RCVTSTAMP); break; case SO_RCVLOWAT: if (val < 0) val = INT_MAX; sk->sk_rcvlowat = val ? : 1; break; case SO_RCVTIMEO: ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen); break; case SO_SNDTIMEO: ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen); break; #ifdef CONFIG_NETDEVICES case SO_BINDTODEVICE: { char devname[IFNAMSIZ]; /* Sorry... */ if (!capable(CAP_NET_RAW)) { ret = -EPERM; break; } /* Bind this socket to a particular device like "eth0", * as specified in the passed interface name. If the * name is "" or the option length is zero the socket * is not bound. */ if (!valbool) { sk->sk_bound_dev_if = 0; } else { if (optlen > IFNAMSIZ - 1) optlen = IFNAMSIZ - 1; memset(devname, 0, sizeof(devname)); if (copy_from_user(devname, optval, optlen)) { ret = -EFAULT; break; } /* Remove any cached route for this socket. */ sk_dst_reset(sk); if (devname[0] == '\0') { sk->sk_bound_dev_if = 0; } else { struct net_device *dev = dev_get_by_name(devname); if (!dev) { ret = -ENODEV; break; } sk->sk_bound_dev_if = dev->ifindex; dev_put(dev); } } break; } #endif case SO_ATTACH_FILTER: ret = -EINVAL; if (optlen == sizeof(struct sock_fprog)) { struct sock_fprog fprog; ret = -EFAULT; if (copy_from_user(&fprog, optval, sizeof(fprog))) break; ret = sk_attach_filter(&fprog, sk); } break; case SO_DETACH_FILTER: rcu_read_lock_bh(); filter = rcu_dereference(sk->sk_filter); if (filter) { rcu_assign_pointer(sk->sk_filter, NULL); sk_filter_release(sk, filter); rcu_read_unlock_bh(); break; } rcu_read_unlock_bh(); ret = -ENONET; break; case SO_PASSSEC: if (valbool) set_bit(SOCK_PASSSEC, &sock->flags); else clear_bit(SOCK_PASSSEC, &sock->flags); break; /* We implement the SO_SNDLOWAT etc to not be settable (1003.1g 5.3) */ default: ret = -ENOPROTOOPT; break; } release_sock(sk); return ret; }
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { int retval = -EIO; char local[12] = {0}; static int opened = 0; int ret = -1; struct net_device *netdev = NULL; PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode; int wait_cnt = 0; printk("WIFI_write: count: %d\n", count); down(&wr_mtx); if (count <= 0) { WIFI_INFO_FUNC("WIFI_write invalid param \n"); goto done; } if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { /*mtk80707 rollback aosp hal*/ local[11] = 0; WIFI_INFO_FUNC("WIFI_write %s\n", local); if (local[0] == '0' && opened == 1) { //TODO //Configure the EINT pin to GPIO mode. p2pmode.u4Enable = 0; p2pmode.u4Mode = 0; /*IF power off already*/ if (power_state == 0) { WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); opened = 0; retval = count; wlan_mode = WLAN_MODE_HALT; goto done; } if (flagIsIFchanged==1) { netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);} else {netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);} while (netdev == NULL && wait_cnt < 10) { WIFI_WARN_FUNC("WMT fail to get wlan0 net device, sleep 300ms\n"); msleep(300); wait_cnt ++; if (flagIsIFchanged==1) { netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);} else { netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME);} } if (wait_cnt >= 10) { WIFI_WARN_FUNC("WMT get wlan0 net device time out\n"); goto done; } if (pf_set_p2p_mode) { ret = pf_set_p2p_mode(netdev, p2pmode); if (ret != 0) { WIFI_WARN_FUNC("WMT trun off p2p & ap mode ret = %d", ret); goto done; } //msleep(300); } dev_put(netdev); netdev = NULL; if (false == mtk_wcn_wifi_func_off()) { WIFI_INFO_FUNC("WMT turn off WIFI fail!\n"); } else { msleep(500); //wait for sdio core remove the wifi card, may need use completition to sync the status WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); opened = 0; retval = count; wlan_mode = WLAN_MODE_HALT; power_state = 0; flagIsIFchanged=0; PowerOnIFname = 0; } } else if (local[0] == '1') { //TODO //Disable EINT(external interrupt), and set the GPIO to EINT mode. if (power_state == 1){ WIFI_INFO_FUNC("WIFI is already on!\n"); retval = count; } else { pf_set_p2p_mode = NULL; if (false == mtk_wcn_wifi_func_on()) { WIFI_WARN_FUNC("WMT turn on WIFI fail!\n"); } else { opened = 1; retval = count; WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); wlan_mode = WLAN_MODE_HALT; power_state = 1; //msleep(300); } } } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { p2pmode.u4Enable = 1; p2pmode.u4Mode = 0; ret = -1; if (power_state ==0) { WIFI_INFO_FUNC("Turn on WIFI first if WIFI is off\n"); if(local[0] == 'A') { PowerOnIFname = 1; //legacy_wlan0 printk("change PoweronIFname\n"); } pf_set_p2p_mode = NULL; if (false == mtk_wcn_wifi_func_on()) { WIFI_WARN_FUNC("WMT turn on WIFI fail!\n"); } else { opened = 1; retval = count; WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); wlan_mode = WLAN_MODE_HALT; power_state = 1; if (local[0] == 'A'){ flagIsIFchanged=1;} } } if (flagIsIFchanged==1) {netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME); } else { netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); if (local[0] == 'A'&&netdev!=NULL) { rtnl_lock(); ret = dev_change_name(netdev,WLAN_LEG_IFACE_NAME); rtnl_unlock(); flagIsIFchanged=1; printk("change_leagcy_name, ret = %d",ret); } } while (netdev == NULL && wait_cnt < 10) { WIFI_WARN_FUNC("WMT fail to get wlan0 net device, sleep 300ms\n"); msleep(300); wait_cnt ++; if (flagIsIFchanged==1) {netdev = dev_get_by_name(&init_net, WLAN_LEG_IFACE_NAME);} else { netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); if (local[0] == 'A'&&netdev!=NULL) { rtnl_lock(); ret = dev_change_name(netdev,WLAN_LEG_IFACE_NAME); rtnl_unlock(); flagIsIFchanged=1; printk("change_leagcy_name, ret = %d",ret); } } } if (wait_cnt >= 10) { WIFI_WARN_FUNC("WMT get wlan0 net device time out\n"); goto done; } if (pf_set_p2p_mode == NULL) { WIFI_INFO_FUNC("set p2p handler is NULL\n"); goto done; } if (wlan_mode == WLAN_MODE_AP&&(local[0] == 'S' || local[0] == 'P') ) { p2pmode.u4Enable = 0; p2pmode.u4Mode = 0; ret = pf_set_p2p_mode(netdev, p2pmode); // msleep(300); WIFI_INFO_FUNC("success to turn off p2p/AP mode\n"); } p2pmode.u4Enable = 1; p2pmode.u4Mode = 0; ret = -1; if (local[0] == 'A') { p2pmode.u4Mode = 1; } ret = pf_set_p2p_mode(netdev, p2pmode); //msleep(300); dev_put(netdev); netdev = NULL; WIFI_INFO_FUNC("WMT WIFI set p2p mode ret=%d\n", ret); if (ret == 0 && (local[0] == 'S' || local[0] == 'P')) { WIFI_INFO_FUNC("wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); wlan_mode = WLAN_MODE_STA_P2P; retval = count; } else if (ret == 0 && local[0] == 'A') { WIFI_INFO_FUNC("wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); wlan_mode = WLAN_MODE_AP; retval = count; } else { WIFI_INFO_FUNC("fail to set wlan mode\n"); } } } done: up(&wr_mtx); if (netdev != NULL) { dev_put(netdev); } printk("WIFI_write: retval: %d\n", retval); if(retval!=count) printk("WIFI_write error\n"); return (retval); }
static int dn_def_dev_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { size_t len; struct net_device *dev; char devname[17]; if (!*lenp || (*ppos && !write)) { *lenp = 0; return 0; } if (write) { if (*lenp > 16) return -E2BIG; if (copy_from_user(devname, buffer, *lenp)) return -EFAULT; devname[*lenp] = 0; strip_it(devname); dev = dev_get_by_name(&init_net, devname); if (dev == NULL) return -ENODEV; if (dev->dn_ptr == NULL) { dev_put(dev); return -ENODEV; } if (dn_dev_set_default(dev, 1)) { dev_put(dev); return -ENODEV; } *ppos += *lenp; return 0; } dev = dn_dev_get_default(); if (dev == NULL) { *lenp = 0; return 0; } strcpy(devname, dev->name); dev_put(dev); len = strlen(devname); devname[len++] = '\n'; if (len > *lenp) len = *lenp; if (len > sizeof devname || copy_to_user(buffer, devname, len)) return -EFAULT; *lenp = len; *ppos += len; return 0; }
static unsigned int route_oif(const struct ipt_route_target_info *route_info, struct sk_buff *skb) { unsigned int ifindex = 0; struct net_device *dev_out = NULL; /* The user set the interface name to use. * Getting the current interface index. */ if ((dev_out = dev_get_by_name(&init_net,route_info->oif))) { ifindex = dev_out->ifindex; } else { /* Unknown interface name : packet dropped */ if (net_ratelimit()) DEBUGP("ipt_ROUTE: oif interface %s not found\n", route_info->oif); return NF_DROP; } /* Trying the standard way of routing packets */ switch (route(skb, ifindex, route_info)) { case 1: dev_put(dev_out); if (route_info->flags & IPT_ROUTE_CONTINUE) return IPT_CONTINUE; ip_direct_send(skb); return NF_STOLEN; case 0: /* Failed to send to oif. Trying the hard way */ if (route_info->flags & IPT_ROUTE_CONTINUE) return NF_DROP; if (net_ratelimit()) DEBUGP("ipt_ROUTE: forcing the use of %i\n", ifindex); /* We have to force the use of an interface. * This interface must be a tunnel interface since * otherwise we can't guess the hw address for * the packet. For a tunnel interface, no hw address * is needed. */ if ((dev_out->type != ARPHRD_TUNNEL) && (dev_out->type != ARPHRD_IPGRE)) { if (net_ratelimit()) DEBUGP("ipt_ROUTE: can't guess the hw addr !\n"); dev_put(dev_out); return NF_DROP; } /* Send the packet. This will also free skb * Do not go through the POST_ROUTING hook because * skb->dst is not set and because it will probably * get confused by the destination IP address. */ skb->dev = dev_out; dev_direct_send(skb); dev_put(dev_out); return NF_STOLEN; default: /* Unexpected error */ dev_put(dev_out); return NF_DROP; } }
static sw_error_t setup_interface_entry(char *list_if, int is_wan) { char temp[IFNAMSIZ*4]; /* Max 4 interface entries right now. */ char *dev_name, *list_all; struct net_device *nat_dev; struct in_device *in_device_lan = NULL; uint8_t *devmac, if_mac_addr[MAC_LEN]; char *br_name; uint32_t vid = 0; sw_error_t setup_error; uint32_t ipv6 = 0; memcpy(temp, list_if, strlen(list_if)+1); list_all = temp; setup_error = SW_OK; while ((dev_name = strsep(&list_all, " ")) != NULL) { nat_dev = dev_get_by_name(&init_net, dev_name); if (NULL == nat_dev) { // printk("%s: Cannot get device %s by name!\n", __FUNCTION__, dev_name); setup_error = SW_FAIL; continue; } #if defined (CONFIG_BRIDGE) if (NULL != nat_dev->br_port) /* under bridge interface. */ { /* Get bridge interface name */ br_name = (char *)nat_dev->br_port->br->dev->name; memcpy (nat_bridge_dev, br_name, sizeof(br_name)); /* Get dmac */ devmac = (uint8_t *)nat_dev->br_port->br->dev->dev_addr; } else #endif /* CONFIG_BRIDGE */ { devmac = (uint8_t *)nat_dev->dev_addr; } /* get vid */ #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) vid = vlan_dev_vlan_id(nat_dev); #else vid = 0; #endif #ifdef CONFIG_IPV6_HWACCEL ipv6 = 1; if (is_wan) { wan_fid = vid; } #else ipv6 = 0; if (is_wan) { if (NF_S17_WAN_TYPE_PPPOEV6 == nf_athrs17_hnat_wan_type) ipv6 = 1; wan_fid = vid; } #endif #ifdef ISISC if (0 == is_wan) /* Not WAN -> LAN */ { /* Setup private and netmask as soon as possible */ in_device_lan = (struct in_device *) nat_dev->ip_ptr; nat_hw_prv_mask_set((a_uint32_t)(in_device_lan->ifa_list->ifa_mask)); nat_hw_prv_base_set((a_uint32_t)(in_device_lan->ifa_list->ifa_address)); } #endif memcpy(if_mac_addr, devmac, MAC_LEN); devmac = if_mac_addr; dev_put(nat_dev); HNAT_PRINTK("DMAC: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", devmac[0], devmac[1], devmac[2], devmac[3], devmac[4], devmac[5]); HNAT_PRINTK("VLAN id: %d\n", vid); if(if_mac_add(devmac, vid, ipv6) != 0) { setup_error = SW_FAIL; continue; } else { setup_error = SW_OK; } } return setup_error; }
static int ixgbe_dcb_pg_scfg(struct sk_buff *skb, struct genl_info *info, int dir) { struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; struct tc_configuration *tc_config = NULL; struct tc_configuration *tc_tmpcfg = NULL; struct nlattr *pg_tb[IXGBE_DCB_PG_A_MAX + 1]; struct nlattr *param_tb[IXGBE_DCB_TC_A_PARAM_MAX + 1]; int i, ret, tc_max; u8 value; u8 changed = 0; if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PG_CFG]) return -EINVAL; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) return -EINVAL; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err; else adapter = netdev_priv(netdev); ret = nla_parse_nested(pg_tb, IXGBE_DCB_PG_A_MAX, info->attrs[DCB_A_PG_CFG], dcb_pg_nest); if (ret) goto err; if (!adapter->dcb_set_bitmap && ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, adapter->ring_feature[RING_F_DCB].indices)) goto err; tc_max = adapter->ring_feature[RING_F_DCB].indices; for (i = PG_A_TC_0; i < tc_max + PG_A_TC_0; i++) { if (!pg_tb[i]) continue; ret = nla_parse_nested(param_tb, IXGBE_DCB_TC_A_PARAM_MAX, pg_tb[i], dcb_tc_param_nest); if (ret) goto err; tc_config = &adapter->dcb_cfg.tc_config[i - PG_A_TC_0]; tc_tmpcfg = &adapter->temp_dcb_cfg.tc_config[i - PG_A_TC_0]; if (param_tb[TC_A_PARAM_STRICT_PRIO]) { value = nla_get_u8(param_tb[TC_A_PARAM_STRICT_PRIO]); tc_tmpcfg->path[dir].prio_type = value; if (tc_tmpcfg->path[dir].prio_type != tc_config->path[dir].prio_type) changed = 1; } if (param_tb[TC_A_PARAM_BW_GROUP_ID]) { value = nla_get_u8(param_tb[TC_A_PARAM_BW_GROUP_ID]); tc_tmpcfg->path[dir].bwg_id = value; if (tc_tmpcfg->path[dir].bwg_id != tc_config->path[dir].bwg_id) changed = 1; } if (param_tb[TC_A_PARAM_BW_PCT_IN_GROUP]) { value = nla_get_u8(param_tb[TC_A_PARAM_BW_PCT_IN_GROUP]); tc_tmpcfg->path[dir].bwg_percent = value; if (tc_tmpcfg->path[dir].bwg_percent != tc_config->path[dir].bwg_percent) changed = 1; } if (param_tb[TC_A_PARAM_UP_MAPPING]) { value = nla_get_u8(param_tb[TC_A_PARAM_UP_MAPPING]); tc_tmpcfg->path[dir].up_to_tc_bitmap = value; if (tc_tmpcfg->path[dir].up_to_tc_bitmap != tc_config->path[dir].up_to_tc_bitmap) changed = 1; } } for (i = PG_A_BWG_0; i < PG_A_BWG_MAX; i++) { if (!pg_tb[i]) continue; value = nla_get_u8(pg_tb[i]); adapter->temp_dcb_cfg.bw_percentage[dir][i-PG_A_BWG_0] = value; if (adapter->temp_dcb_cfg.bw_percentage[dir][i-PG_A_BWG_0] != adapter->dcb_cfg.bw_percentage[dir][i-PG_A_BWG_0]) changed = 1; } adapter->temp_dcb_cfg.round_robin_enable = false; if (changed) { if (dir == DCB_TX_CONFIG) adapter->dcb_set_bitmap |= BIT_PG_TX; else adapter->dcb_set_bitmap |= BIT_PG_RX; adapter->dcb_set_bitmap |= BIT_RESETLINK; } ret = ixgbe_nl_reply(0, (dir? DCB_C_PGRX_SCFG : DCB_C_PGTX_SCFG), DCB_A_PG_CFG, info); if (ret) goto err; err: dev_put(netdev); return ret; }
static int robo_probe(char *devname) { __u32 phyid; unsigned int i; int err; printk(KERN_INFO PFX "Probing device %s: ", devname); strcpy(robo.ifr.ifr_name, devname); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) if ((robo.dev = dev_get_by_name(devname)) == NULL) { #else if ((robo.dev = dev_get_by_name(&init_net, devname)) == NULL) { #endif printk("No such device\n"); return 1; } robo.device = devname; for (i = 0; i < 5; i++) robo.port[i] = i; robo.port[5] = 8; /* try access using MII ioctls - get phy address */ if (do_ioctl(SIOCGMIIPHY, NULL) < 0) { robo.use_et = 1; robo.phy_addr = ROBO_PHY_ADDR; } else { /* got phy address check for robo address */ struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &robo.ifr.ifr_data; if ((mii->phy_id != ROBO_PHY_ADDR) && (mii->phy_id != ROBO_PHY_ADDR_TG3)) { printk("Invalid phy address (%d)\n", mii->phy_id); return 1; } robo.use_et = 0; /* The robo has a fixed PHY address that is different from the * Tigon3 PHY address. */ robo.phy_addr = ROBO_PHY_ADDR; } phyid = mdio_read(robo.phy_addr, 0x2) | (mdio_read(robo.phy_addr, 0x3) << 16); if (phyid == 0xffffffff || phyid == 0x55210022) { printk("No Robo switch in managed mode found\n"); return 1; } /* Get the device ID */ for (i = 0; i < 10; i++) { robo.devid = robo_read16(ROBO_MGMT_PAGE, ROBO_DEVICE_ID); if (robo.devid) break; udelay(10); } if (!robo.devid) robo.devid = ROBO_DEVICE_ID_5325; /* Fake it */ robo.is_5350 = robo_vlan5350(); robo_switch_reset(); err = robo_switch_enable(); if (err) return err; printk("found!\n"); return 0; } static int handle_vlan_port_read(void *driver, char *buf, int nr) { __u16 val16; int len = 0; int j; val16 = (nr) /* vlan */ | (0 << 12) /* read */ | (1 << 13) /* enable */; if (robo.is_5350) { u32 val32; robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16); /* actual read */ val32 = robo_read32(ROBO_VLAN_PAGE, ROBO_VLAN_READ); if ((val32 & (1 << 20)) /* valid */) { for (j = 0; j < 6; j++) { if (val32 & (1 << j)) { len += sprintf(buf + len, "%d", j); if (val32 & (1 << (j + 6))) { if (j == 5) buf[len++] = 'u'; } else { buf[len++] = 't'; if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr) buf[len++] = '*'; } buf[len++] = '\t'; } } len += sprintf(buf + len, "\n"); } } else { robo_write16(ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS, val16); /* actual read */ val16 = robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_READ); if ((val16 & (1 << 14)) /* valid */) { for (j = 0; j < 6; j++) { if (val16 & (1 << j)) { len += sprintf(buf + len, "%d", j); if (val16 & (1 << (j + 7))) { if (j == 5) buf[len++] = 'u'; } else { buf[len++] = 't'; if (robo_read16(ROBO_VLAN_PAGE, ROBO_VLAN_PORT0_DEF_TAG + (j << 1)) == nr) buf[len++] = '*'; } buf[len++] = '\t'; } } len += sprintf(buf + len, "\n"); } } buf[len] = '\0'; return len; }
int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb) { struct dump_phy_data data = { .cb = cb, .skb = skb, .s_idx = cb->args[0], .idx = 0, }; pr_debug("%s\n", __func__); wpan_phy_for_each(ieee802154_dump_phy_iter, &data); cb->args[0] = data.idx; return skb->len; } int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; struct wpan_phy *phy; const char *name; const char *devname; int rc = -ENOBUFS; struct net_device *dev; int type = __IEEE802154_DEV_INVALID; unsigned char name_assign_type; pr_debug("%s\n", __func__); if (!info->attrs[IEEE802154_ATTR_PHY_NAME]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ if (info->attrs[IEEE802154_ATTR_DEV_NAME]) { devname = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]); if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ name_assign_type = NET_NAME_USER; } else { devname = "wpan%d"; name_assign_type = NET_NAME_ENUM; } if (strlen(devname) >= IFNAMSIZ) return -ENAMETOOLONG; phy = wpan_phy_find(name); if (!phy) return -ENODEV; msg = ieee802154_nl_new_reply(info, 0, IEEE802154_ADD_IFACE); if (!msg) goto out_dev; if (info->attrs[IEEE802154_ATTR_HW_ADDR] && nla_len(info->attrs[IEEE802154_ATTR_HW_ADDR]) != IEEE802154_ADDR_LEN) { rc = -EINVAL; goto nla_put_failure; } if (info->attrs[IEEE802154_ATTR_DEV_TYPE]) { type = nla_get_u8(info->attrs[IEEE802154_ATTR_DEV_TYPE]); if (type >= __IEEE802154_DEV_MAX) { rc = -EINVAL; goto nla_put_failure; } } dev = rdev_add_virtual_intf_deprecated(wpan_phy_to_rdev(phy), devname, name_assign_type, type); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure; } dev_hold(dev); if (info->attrs[IEEE802154_ATTR_HW_ADDR]) { struct sockaddr addr; addr.sa_family = ARPHRD_IEEE802154; nla_memcpy(&addr.sa_data, info->attrs[IEEE802154_ATTR_HW_ADDR], IEEE802154_ADDR_LEN); /* strangely enough, some callbacks (inetdev_event) from * dev_set_mac_address require RTNL_LOCK */ rtnl_lock(); rc = dev_set_mac_address(dev, &addr, NULL); rtnl_unlock(); if (rc) goto dev_unregister; } if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name)) goto nla_put_failure; dev_put(dev); wpan_phy_put(phy); return ieee802154_nl_reply(msg, info); dev_unregister: rtnl_lock(); /* del_iface must be called with RTNL lock */ rdev_del_virtual_intf_deprecated(wpan_phy_to_rdev(phy), dev); dev_put(dev); rtnl_unlock(); nla_put_failure: nlmsg_free(msg); out_dev: wpan_phy_put(phy); return rc; } int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; struct wpan_phy *phy; const char *name; int rc; struct net_device *dev; pr_debug("%s\n", __func__); if (!info->attrs[IEEE802154_ATTR_DEV_NAME]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]); if (name[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* name should be null-terminated */ rc = -ENODEV; dev = dev_get_by_name(genl_info_net(info), name); if (!dev) return rc; if (dev->type != ARPHRD_IEEE802154) goto out; phy = dev->ieee802154_ptr->wpan_phy; BUG_ON(!phy); get_device(&phy->dev); rc = -EINVAL; /* phy name is optional, but should be checked if it's given */ if (info->attrs[IEEE802154_ATTR_PHY_NAME]) { struct wpan_phy *phy2; const char *pname = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); if (pname[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') /* name should be null-terminated */ goto out_dev; phy2 = wpan_phy_find(pname); if (!phy2) goto out_dev; if (phy != phy2) { wpan_phy_put(phy2); goto out_dev; } } rc = -ENOBUFS; msg = ieee802154_nl_new_reply(info, 0, IEEE802154_DEL_IFACE); if (!msg) goto out_dev; rtnl_lock(); rdev_del_virtual_intf_deprecated(wpan_phy_to_rdev(phy), dev); /* We don't have device anymore */ dev_put(dev); dev = NULL; rtnl_unlock(); if (nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, name)) goto nla_put_failure; wpan_phy_put(phy); return ieee802154_nl_reply(msg, info); nla_put_failure: nlmsg_free(msg); out_dev: wpan_phy_put(phy); out: if (dev) dev_put(dev); return rc; }
static int ixgbe_dcb_pg_gcfg(struct sk_buff *skb, struct genl_info *info, int dir) { void *data; struct sk_buff *dcb_skb = NULL; struct nlattr *pg_nest, *param_nest, *tb; struct nlattr *pg_tb[IXGBE_DCB_PG_A_MAX + 1]; struct nlattr *param_tb[IXGBE_DCB_TC_A_PARAM_MAX + 1]; struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; struct tc_configuration *tc_config = NULL; struct tc_bw_alloc *tc = NULL; int ret = -ENOMEM; int i, tc_max; if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PG_CFG]) return -EINVAL; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) return -EINVAL; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err_out; else adapter = netdev_priv(netdev); ret = nla_parse_nested(pg_tb, IXGBE_DCB_PG_A_MAX, info->attrs[DCB_A_PG_CFG], dcb_pg_nest); if (ret) goto err; dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!dcb_skb) goto err; data = genlmsg_put_reply(dcb_skb, info, &dcb_family, 0, (dir) ? DCB_C_PGRX_GCFG : DCB_C_PGTX_GCFG); if (!data) goto err; pg_nest = nla_nest_start(dcb_skb, DCB_A_PG_CFG); if (!pg_nest) goto err; tc_max = adapter->ring_feature[RING_F_DCB].indices; for (i = PG_A_TC_0; i < tc_max + PG_A_TC_0; i++) { if (!pg_tb[i] && !pg_tb[PG_A_TC_ALL]) continue; if (pg_tb[PG_A_TC_ALL]) tb = pg_tb[PG_A_TC_ALL]; else tb = pg_tb[i]; ret = nla_parse_nested(param_tb, IXGBE_DCB_TC_A_PARAM_MAX, tb, dcb_tc_param_nest); if (ret) goto err_pg; param_nest = nla_nest_start(dcb_skb, i); if (!param_nest) goto err_pg; tc_config = &adapter->dcb_cfg.tc_config[i - PG_A_TC_0]; tc = &adapter->dcb_cfg.tc_config[i - PG_A_TC_0].path[dir]; if (param_tb[TC_A_PARAM_STRICT_PRIO] || param_tb[TC_A_PARAM_ALL]) { ret = nla_put_u8(dcb_skb, TC_A_PARAM_STRICT_PRIO, tc->prio_type); if (ret) goto err_param; } if (param_tb[TC_A_PARAM_BW_GROUP_ID] || param_tb[TC_A_PARAM_ALL]) { ret = nla_put_u8(dcb_skb, TC_A_PARAM_BW_GROUP_ID, tc->bwg_id); if (ret) goto err_param; } if (param_tb[TC_A_PARAM_BW_PCT_IN_GROUP] || param_tb[TC_A_PARAM_ALL]) { ret = nla_put_u8(dcb_skb, TC_A_PARAM_BW_PCT_IN_GROUP, tc->bwg_percent); if (ret) goto err_param; } if (param_tb[TC_A_PARAM_UP_MAPPING] || param_tb[TC_A_PARAM_ALL]) { ret = nla_put_u8(dcb_skb, TC_A_PARAM_UP_MAPPING, tc->up_to_tc_bitmap); if (ret) goto err_param; } nla_nest_end(dcb_skb, param_nest); } for (i = PG_A_BWG_0; i < PG_A_BWG_MAX; i++) { if (!pg_tb[i] && !pg_tb[PG_A_BWG_ALL]) continue; ret = nla_put_u8(dcb_skb, i, adapter->dcb_cfg.bw_percentage[dir][i-PG_A_BWG_0]); if (ret) goto err_pg; } nla_nest_end(dcb_skb, pg_nest); genlmsg_end(dcb_skb, data); ret = genlmsg_reply(dcb_skb, info); if (ret) goto err; dev_put(netdev); return 0; err_param: DPRINTK(DRV, ERR, "Error in get pg %s.\n", dir?"rx":"tx"); nla_nest_cancel(dcb_skb, param_nest); err_pg: nla_nest_cancel(dcb_skb, pg_nest); err: kfree(dcb_skb); err_out: dev_put(netdev); return ret; }
/*-----------------------------------------------------------------*/ int wifi_reset_end(void) { struct net_device *netdev = NULL; PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode; int wait_cnt = 0; int ret = -1; WIFI_WARN_FUNC("WIFI state recovering...\n"); if (powered == 1) { /* WIFI is on before whole chip reset, reopen it now */ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); goto done; } else { WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); } if (pf_set_p2p_mode == NULL) { WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); goto done; } netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); while (netdev == NULL && wait_cnt < 10) { WIFI_ERR_FUNC("Fail to get wlan0 net device, sleep 300ms\n"); msleep(300); wait_cnt++; netdev = dev_get_by_name(&init_net, WLAN_IFACE_NAME); } if (wait_cnt >= 10) { WIFI_ERR_FUNC("Get wlan0 net device timeout\n"); goto done; } if (wlan_mode == WLAN_MODE_STA_P2P) { p2pmode.u4Enable = 1; p2pmode.u4Mode = 0; if (pf_set_p2p_mode(netdev, p2pmode) != 0) { WIFI_ERR_FUNC("Set wlan mode fail\n"); } else { WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_STA_P2P); ret = 0; } } else if (wlan_mode == WLAN_MODE_AP) { p2pmode.u4Enable = 1; p2pmode.u4Mode = 1; if (pf_set_p2p_mode(netdev, p2pmode) != 0) { WIFI_ERR_FUNC("Set wlan mode fail\n"); } else { WIFI_WARN_FUNC("Set wlan mode %d\n", WLAN_MODE_AP); ret = 0; } } done: if (netdev != NULL) { dev_put(netdev); } } else { /* WIFI is off before whole chip reset, do nothing */ ret = 0; } up(&wr_mtx); return ret; }
static int ixgbe_dcb_spfccfg(struct sk_buff *skb, struct genl_info *info) { struct nlattr *tb[IXGBE_DCB_PFC_A_UP_MAX + 1]; struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; int i, ret = -ENOMEM; u8 setting; u8 changed = 0; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) return -EINVAL; adapter = netdev_priv(netdev); if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PFC_CFG]) return -EINVAL; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err; else adapter = netdev_priv(netdev); ret = nla_parse_nested(tb, IXGBE_DCB_PFC_A_UP_MAX, info->attrs[DCB_A_PFC_CFG], dcb_pfc_up_nest); if (ret) goto err; if (!adapter->dcb_set_bitmap && ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg, adapter->ring_feature[RING_F_DCB].indices)) { ret = -EINVAL; goto err; } for (i = PFC_A_UP_0; i < PFC_A_UP_MAX; i++) { if (!tb[i]) continue; setting = nla_get_u8(tb[i]); adapter->temp_dcb_cfg.tc_config[i-PFC_A_UP_0].dcb_pfc = setting; if (adapter->temp_dcb_cfg.tc_config[i-PFC_A_UP_0].dcb_pfc != adapter->dcb_cfg.tc_config[i-PFC_A_UP_0].dcb_pfc) changed = 1; } if (changed) adapter->dcb_set_bitmap |= BIT_PFC; ret = ixgbe_nl_reply(0, DCB_C_PFC_SCFG, DCB_A_PFC_CFG, info); if (ret) goto err; err: dev_put(netdev); return ret; }
/* * dev_remote_control_access() */ void *dev_remote_control_access(cpu_gen_t *cpu,struct vdevice *dev, m_uint32_t offset,u_int op_size,u_int op_type, m_uint64_t *data) { vm_instance_t *vm = cpu->vm; struct remote_data *d = dev->priv_data; struct vdevice *storage_dev; size_t len; if (op_type == MTS_READ) *data = 0; #if DEBUG_ACCESS if (op_type == MTS_READ) { cpu_log(cpu,"REMOTE","reading reg 0x%x at pc=0x%llx\n", offset,cpu_get_pc(cpu)); } else { cpu_log(cpu,"REMOTE","writing reg 0x%x at pc=0x%llx, data=0x%llx\n", offset,cpu_get_pc(cpu),*data); } #endif switch(offset) { /* ROM Identification tag */ case 0x000: if (op_type == MTS_READ) *data = ROM_ID; break; /* CPU ID */ case 0x004: if (op_type == MTS_READ) *data = cpu->id; break; /* Display CPU registers */ case 0x008: if (op_type == MTS_WRITE) cpu->reg_dump(cpu); break; /* Display CPU memory info */ case 0x00c: if (op_type == MTS_WRITE) cpu->mmu_dump(cpu); break; /* Reserved/Unused */ case 0x010: break; /* RAM size */ case 0x014: if (op_type == MTS_READ) *data = vm->ram_size; break; /* ROM size */ case 0x018: if (op_type == MTS_READ) *data = vm->rom_size; break; /* NVRAM size */ case 0x01c: if (op_type == MTS_READ) *data = vm->nvram_size; break; /* IOMEM size */ case 0x020: if (op_type == MTS_READ) *data = vm->iomem_size; break; /* Config Register */ case 0x024: if (op_type == MTS_READ) *data = vm->conf_reg; break; /* ELF entry point */ case 0x028: if (op_type == MTS_READ) *data = vm->ios_entry_point; break; /* ELF machine id */ case 0x02c: if (op_type == MTS_READ) *data = vm->elf_machine_id; break; /* Restart IOS Image */ case 0x030: /* not implemented */ break; /* Stop the virtual machine */ case 0x034: // FIXME: WTF is this for?!?!? //vm->status = VM_STATUS_SHUTDOWN; break; /* Debugging/Log message: /!\ physical address */ case 0x038: if (op_type == MTS_WRITE) { len = physmem_strlen(vm,*data); if (len < sizeof(d->con_buffer)) { physmem_copy_from_vm(vm,d->con_buffer,*data,len+1); vm_log(vm,"ROM",d->con_buffer); } } break; /* Console Buffering */ case 0x03c: if (op_type == MTS_WRITE) { if (d->con_buf_pos < (sizeof(d->con_buffer)-1)) { d->con_buffer[d->con_buf_pos++] = *data & 0xFF; d->con_buffer[d->con_buf_pos] = 0; if (d->con_buffer[d->con_buf_pos-1] == '\n') { vm_log(vm,"ROM","%s",d->con_buffer); d->con_buf_pos = 0; } } else d->con_buf_pos = 0; } break; /* Console output */ case 0x040: if (op_type == MTS_WRITE) vtty_put_char(vm->vtty_con,(char)*data); break; /* NVRAM address */ case 0x044: if (op_type == MTS_READ) { if ((storage_dev = dev_get_by_name(vm,"nvram"))) *data = storage_dev->phys_addr; if ((storage_dev = dev_get_by_name(vm,"ssa"))) *data = storage_dev->phys_addr; if (cpu->type == CPU_TYPE_MIPS64) *data += MIPS_KSEG1_BASE; } break; /* IO memory size for Smart-Init (C3600, others ?) */ case 0x048: if (op_type == MTS_READ) *data = vm->nm_iomem_size; break; /* Cookie position selector */ case 0x04c: if (op_type == MTS_READ) *data = d->cookie_pos; else d->cookie_pos = *data; break; /* Cookie data */ case 0x050: if ((op_type == MTS_READ) && (d->cookie_pos < 64)) *data = vm->chassis_cookie[d->cookie_pos]; break; /* ROMMON variable */ case 0x054: if (op_type == MTS_WRITE) { if (d->var_buf_pos < (sizeof(d->var_buffer)-1)) { d->var_buffer[d->var_buf_pos++] = *data & 0xFF; d->var_buffer[d->var_buf_pos] = 0; } else d->var_buf_pos = 0; } else { if (d->var_buf_pos < (sizeof(d->var_buffer)-1)) { *data = d->var_buffer[d->var_buf_pos++]; } else { d->var_buf_pos = 0; *data = 0; } } break; /* ROMMON variable command */ case 0x058: if (op_type == MTS_WRITE) { switch(*data & 0xFF) { case ROMMON_SET_VAR: d->var_status = rommon_var_add_str(&vm->rommon_vars, d->var_buffer); d->var_buf_pos = 0; break; case ROMMON_GET_VAR: d->var_status = rommon_var_get(&vm->rommon_vars, d->var_buffer, d->var_buffer, sizeof(d->var_buffer)); d->var_buf_pos = 0; break; case ROMMON_CLEAR_VAR_STAT: d->var_buf_pos = 0; break; default: d->var_status = -1; } } else { *data = d->var_status; } break; } return NULL; }
static int ixgbe_dcb_gpfccfg(struct sk_buff *skb, struct genl_info *info) { void *data; struct sk_buff *dcb_skb = NULL; struct nlattr *tb[IXGBE_DCB_PFC_A_UP_MAX + 1], *nest; struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; int ret = -ENOMEM; int i; if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_PFC_CFG]) return -EINVAL; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) return -EINVAL; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err_out; else adapter = netdev_priv(netdev); ret = nla_parse_nested(tb, IXGBE_DCB_PFC_A_UP_MAX, info->attrs[DCB_A_PFC_CFG], dcb_pfc_up_nest); if (ret) goto err; dcb_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!dcb_skb) goto err; data = genlmsg_put_reply(dcb_skb, info, &dcb_family, 0, DCB_C_PFC_GCFG); if (!data) goto err; nest = nla_nest_start(dcb_skb, DCB_A_PFC_CFG); if (!nest) goto err; for (i = PFC_A_UP_0; i < PFC_A_UP_MAX; i++) { if (!tb[i] && !tb[PFC_A_UP_ALL]) continue; ret = nla_put_u8(dcb_skb, i, adapter->dcb_cfg.tc_config[i-PFC_A_UP_0].dcb_pfc); if (ret) { nla_nest_cancel(dcb_skb, nest); goto err; } } nla_nest_end(dcb_skb, nest); genlmsg_end(dcb_skb, data); ret = genlmsg_reply(dcb_skb, info); if (ret) goto err; dev_put(netdev); return 0; err: DPRINTK(DRV, ERR, "Error in get pfc stats.\n"); kfree(dcb_skb); err_out: dev_put(netdev); return ret; }
static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg) { struct ifreq ifr; struct ec_device *edev; struct net_device *dev; struct sockaddr_ec *sec; /* * Fetch the caller's info block into kernel space */ if (copy_from_user(&ifr, arg, sizeof(struct ifreq))) return -EFAULT; if ((dev = dev_get_by_name(ifr.ifr_name)) == NULL) return -ENODEV; sec = (struct sockaddr_ec *)&ifr.ifr_addr; switch (cmd) { case SIOCSIFADDR: edev = dev->ec_ptr; if (edev == NULL) { /* Magic up a new one. */ edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL); if (edev == NULL) { printk("af_ec: memory squeeze.\n"); dev_put(dev); return -ENOMEM; } memset(edev, 0, sizeof(struct ec_device)); dev->ec_ptr = edev; } else net2dev_map[edev->net] = NULL; edev->station = sec->addr.station; edev->net = sec->addr.net; net2dev_map[sec->addr.net] = dev; if (!net2dev_map[0]) net2dev_map[0] = dev; dev_put(dev); return 0; case SIOCGIFADDR: edev = dev->ec_ptr; if (edev == NULL) { dev_put(dev); return -ENODEV; } memset(sec, 0, sizeof(struct sockaddr_ec)); sec->addr.station = edev->station; sec->addr.net = edev->net; sec->sec_family = AF_ECONET; dev_put(dev); if (copy_to_user(arg, &ifr, sizeof(struct ifreq))) return -EFAULT; return 0; } dev_put(dev); return -EINVAL; }
static int ixgbe_dcb_set_all(struct sk_buff *skb, struct genl_info *info) { struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; int ret = -ENOMEM; u8 value; u8 retval = 0; if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_SET_ALL]) goto err; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) goto err; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err_out; else adapter = netdev_priv(netdev); if (!(adapter->flags & IXGBE_FLAG_DCA_CAPABLE)) { ret = -EINVAL; goto err_out; } value = nla_get_u8(info->attrs[DCB_A_SET_ALL]); if ((value & 1) != value) { DPRINTK(DRV, ERR, "Value is not 1 or 0, it is %d.\n", value); } else { if (!adapter->dcb_set_bitmap) { retval = 1; goto out; } while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, adapter->ring_feature[RING_F_DCB].indices); if (ret) { clear_bit(__IXGBE_RESETTING, &adapter->state); goto err_out; } ixgbe_down(adapter); ixgbe_up(adapter); adapter->dcb_set_bitmap = 0x00; clear_bit(__IXGBE_RESETTING, &adapter->state); } out: ret = ixgbe_nl_reply(retval, DCB_C_SET_ALL, DCB_A_SET_ALL, info); if (ret) goto err_out; err_out: dev_put(netdev); err: return ret; }
int sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk=sock->sk; struct sk_filter *filter; int val; int valbool; struct linger ling; int ret = 0; /* * Options without arguments */ #ifdef SO_DONTLINGER /* Compatibility item... */ switch (optname) { case SO_DONTLINGER: sock_reset_flag(sk, SOCK_LINGER); return 0; } #endif if(optlen<sizeof(int)) return(-EINVAL); if (get_user(val, (int __user *)optval)) return -EFAULT; valbool = val?1:0; lock_sock(sk); switch(optname) { case SO_DEBUG: if(val && !capable(CAP_NET_ADMIN)) { ret = -EACCES; } else sk->sk_debug = valbool; break; case SO_REUSEADDR: sk->sk_reuse = valbool; break; case SO_TYPE: case SO_ERROR: ret = -ENOPROTOOPT; break; case SO_DONTROUTE: sk->sk_localroute = valbool; break; case SO_BROADCAST: sock_valbool_flag(sk, SOCK_BROADCAST, valbool); break; case SO_SNDBUF: /* Don't error on this BSD doesn't and if you think about it this is right. Otherwise apps have to play 'guess the biggest size' games. RCVBUF/SNDBUF are treated in BSD as hints */ if (val > sysctl_wmem_max) val = sysctl_wmem_max; sk->sk_userlocks |= SOCK_SNDBUF_LOCK; if ((val * 2) < SOCK_MIN_SNDBUF) sk->sk_sndbuf = SOCK_MIN_SNDBUF; else sk->sk_sndbuf = val * 2; /* * Wake up sending tasks if we * upped the value. */ sk->sk_write_space(sk); break; case SO_RCVBUF: /* Don't error on this BSD doesn't and if you think about it this is right. Otherwise apps have to play 'guess the biggest size' games. RCVBUF/SNDBUF are treated in BSD as hints */ if (val > sysctl_rmem_max) val = sysctl_rmem_max; sk->sk_userlocks |= SOCK_RCVBUF_LOCK; /* FIXME: is this lower bound the right one? */ if ((val * 2) < SOCK_MIN_RCVBUF) sk->sk_rcvbuf = SOCK_MIN_RCVBUF; else sk->sk_rcvbuf = val * 2; break; case SO_KEEPALIVE: #ifdef CONFIG_INET if (sk->sk_protocol == IPPROTO_TCP) tcp_set_keepalive(sk, valbool); #endif sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool); break; case SO_OOBINLINE: sock_valbool_flag(sk, SOCK_URGINLINE, valbool); break; case SO_NO_CHECK: sk->sk_no_check = valbool; break; case SO_PRIORITY: if ((val >= 0 && val <= 6) || capable(CAP_NET_ADMIN)) sk->sk_priority = val; else ret = -EPERM; break; case SO_LINGER: if(optlen<sizeof(ling)) { ret = -EINVAL; /* 1003.1g */ break; } if (copy_from_user(&ling,optval,sizeof(ling))) { ret = -EFAULT; break; } if (!ling.l_onoff) sock_reset_flag(sk, SOCK_LINGER); else { #if (BITS_PER_LONG == 32) if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; else #endif sk->sk_lingertime = ling.l_linger * HZ; sock_set_flag(sk, SOCK_LINGER); } break; case SO_BSDCOMPAT: sock_warn_obsolete_bsdism("setsockopt"); break; case SO_PASSCRED: sock->passcred = valbool; break; case SO_TIMESTAMP: sk->sk_rcvtstamp = valbool; break; case SO_RCVLOWAT: if (val < 0) val = INT_MAX; sk->sk_rcvlowat = val ? : 1; break; case SO_RCVTIMEO: ret = sock_set_timeout(&sk->sk_rcvtimeo, optval, optlen); break; case SO_SNDTIMEO: ret = sock_set_timeout(&sk->sk_sndtimeo, optval, optlen); break; #ifdef CONFIG_NETDEVICES case SO_BINDTODEVICE: { char devname[IFNAMSIZ]; /* Sorry... */ if (!capable(CAP_NET_RAW)) { ret = -EPERM; break; } /* Bind this socket to a particular device like "eth0", * as specified in the passed interface name. If the * name is "" or the option length is zero the socket * is not bound. */ if (!valbool) { sk->sk_bound_dev_if = 0; } else { if (optlen > IFNAMSIZ) optlen = IFNAMSIZ; if (copy_from_user(devname, optval, optlen)) { ret = -EFAULT; break; } /* Remove any cached route for this socket. */ sk_dst_reset(sk); if (devname[0] == '\0') { sk->sk_bound_dev_if = 0; } else { struct net_device *dev = dev_get_by_name(devname); if (!dev) { ret = -ENODEV; break; } sk->sk_bound_dev_if = dev->ifindex; dev_put(dev); } } break; } #endif case SO_ATTACH_FILTER: ret = -EINVAL; if (optlen == sizeof(struct sock_fprog)) { struct sock_fprog fprog; ret = -EFAULT; if (copy_from_user(&fprog, optval, sizeof(fprog))) break; ret = sk_attach_filter(&fprog, sk); } break; case SO_DETACH_FILTER: spin_lock_bh(&sk->sk_lock.slock); filter = sk->sk_filter; if (filter) { sk->sk_filter = NULL; spin_unlock_bh(&sk->sk_lock.slock); sk_filter_release(sk, filter); break; } spin_unlock_bh(&sk->sk_lock.slock); ret = -ENONET; break; /* We implement the SO_SNDLOWAT etc to not be settable (1003.1g 5.3) */ default: ret = -ENOPROTOOPT; break; } release_sock(sk); return ret; }
static int ixgbe_dcb_sstate(struct sk_buff *skb, struct genl_info *info) { struct net_device *netdev = NULL; struct ixgbe_adapter *adapter = NULL; int ret = -EINVAL; u8 value; if (!info->attrs[DCB_A_IFNAME] || !info->attrs[DCB_A_STATE]) goto err; netdev = dev_get_by_name(&init_net, nla_data(info->attrs[DCB_A_IFNAME])); if (!netdev) goto err; ret = ixgbe_dcb_check_adapter(netdev); if (ret) goto err_out; else adapter = netdev_priv(netdev); value = nla_get_u8(info->attrs[DCB_A_STATE]); if ((value & 1) != value) { DPRINTK(DRV, ERR, "Value is not 1 or 0, it is %d.\n", value); } else { switch (value) { case 0: if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { if (netdev->flags & IFF_UP) #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops->ndo_stop(netdev); #else netdev->stop(netdev); #endif ixgbe_clear_interrupt_scheme(adapter); adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED; if (adapter->flags & IXGBE_FLAG_RSS_CAPABLE) adapter->flags |= IXGBE_FLAG_RSS_ENABLED; ixgbe_init_interrupt_scheme(adapter); ixgbe_reset(adapter); if (netdev->flags & IFF_UP) #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops->ndo_open(netdev); #else netdev->open(netdev); #endif break; } else { /* Nothing to do, already off */ goto out; } case 1: if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { /* Nothing to do, already on */ goto out; } else if (!(adapter->flags & IXGBE_FLAG_DCB_CAPABLE)) { DPRINTK(DRV, ERR, "Enable failed. Make sure " "the driver can enable MSI-X.\n"); ret = -EINVAL; goto err_out; } else { if (netdev->flags & IFF_UP) #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops->ndo_stop(netdev); #else netdev->stop(netdev); #endif ixgbe_clear_interrupt_scheme(adapter); adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; adapter->flags |= IXGBE_FLAG_DCB_ENABLED; adapter->dcb_cfg.support.capabilities = (IXGBE_DCB_PG_SUPPORT | IXGBE_DCB_PFC_SUPPORT | IXGBE_DCB_GSP_SUPPORT); if (adapter->hw.mac.type == ixgbe_mac_82599EB) { DPRINTK(DRV, INFO, "DCB enabled, " "disabling Flow Director\n"); adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE; adapter->dcb_cfg.support.capabilities |= IXGBE_DCB_UP2TC_SUPPORT; } adapter->ring_feature[RING_F_DCB].indices = 8; ixgbe_init_interrupt_scheme(adapter); ixgbe_reset(adapter); if (netdev->flags & IFF_UP) #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops->ndo_open(netdev); #else netdev->open(netdev); #endif break; } } } out: ret = ixgbe_nl_reply(0, DCB_C_SSTATE, DCB_A_STATE, info); if (ret) goto err_out; err_out: dev_put(netdev); err: return ret; }
static int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb) { struct dump_phy_data data = { .cb = cb, .skb = skb, .s_idx = cb->args[0], .idx = 0, }; pr_debug("%s\n", __func__); wpan_phy_for_each(ieee802154_dump_phy_iter, &data); cb->args[0] = data.idx; return skb->len; } static int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; struct wpan_phy *phy; const char *name; const char *devname; int rc = -ENOBUFS; struct net_device *dev; pr_debug("%s\n", __func__); if (!info->attrs[IEEE802154_ATTR_PHY_NAME]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); if (name[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ if (info->attrs[IEEE802154_ATTR_DEV_NAME]) { devname = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]); if (devname[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* phy name should be null-terminated */ } else { devname = "wpan%d"; } if (strlen(devname) >= IFNAMSIZ) return -ENAMETOOLONG; phy = wpan_phy_find(name); if (!phy) return -ENODEV; msg = ieee802154_nl_new_reply(info, 0, IEEE802154_ADD_IFACE); if (!msg) goto out_dev; if (!phy->add_iface) { rc = -EINVAL; goto nla_put_failure; } dev = phy->add_iface(phy, devname); if (IS_ERR(dev)) { rc = PTR_ERR(dev); goto nla_put_failure; } NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)); NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name); dev_put(dev); wpan_phy_put(phy); return ieee802154_nl_reply(msg, info); nla_put_failure: nlmsg_free(msg); out_dev: wpan_phy_put(phy); return rc; } static int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info) { struct sk_buff *msg; struct wpan_phy *phy; const char *name; int rc; struct net_device *dev; pr_debug("%s\n", __func__); if (!info->attrs[IEEE802154_ATTR_DEV_NAME]) return -EINVAL; name = nla_data(info->attrs[IEEE802154_ATTR_DEV_NAME]); if (name[nla_len(info->attrs[IEEE802154_ATTR_DEV_NAME]) - 1] != '\0') return -EINVAL; /* name should be null-terminated */ dev = dev_get_by_name(genl_info_net(info), name); if (!dev) return -ENODEV; phy = ieee802154_mlme_ops(dev)->get_phy(dev); BUG_ON(!phy); rc = -EINVAL; /* phy name is optional, but should be checked if it's given */ if (info->attrs[IEEE802154_ATTR_PHY_NAME]) { struct wpan_phy *phy2; const char *pname = nla_data(info->attrs[IEEE802154_ATTR_PHY_NAME]); if (pname[nla_len(info->attrs[IEEE802154_ATTR_PHY_NAME]) - 1] != '\0') /* name should be null-terminated */ goto out_dev; phy2 = wpan_phy_find(pname); if (!phy2) goto out_dev; if (phy != phy2) { wpan_phy_put(phy2); goto out_dev; } } rc = -ENOBUFS; msg = ieee802154_nl_new_reply(info, 0, IEEE802154_DEL_IFACE); if (!msg) goto out_dev; if (!phy->del_iface) { rc = -EINVAL; goto nla_put_failure; } rtnl_lock(); phy->del_iface(phy, dev); /* We don't have device anymore */ dev_put(dev); dev = NULL; rtnl_unlock(); NLA_PUT_STRING(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)); NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, name); wpan_phy_put(phy); return ieee802154_nl_reply(msg, info); nla_put_failure: nlmsg_free(msg); out_dev: wpan_phy_put(phy); if (dev) dev_put(dev); return rc; } static struct genl_ops ieee802154_phy_ops[] = { IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy, ieee802154_dump_phy), IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface), IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface), }; /* * No need to unregister as family unregistration will do it. */ int nl802154_phy_register(void) { int i; int rc; for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) { rc = genl_register_ops(&nl802154_family, &ieee802154_phy_ops[i]); if (rc) return rc; } return 0; }
ssize_t WIFI_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { INT32 retval = -EIO; INT8 local[12] = {0}; struct net_device *netdev = NULL; PARAM_CUSTOM_P2P_SET_STRUC_T p2pmode; INT32 wait_cnt = 0; down(&wr_mtx); if (count <= 0) { WIFI_ERR_FUNC("WIFI_write invalid param\n"); goto done; } if (0 == copy_from_user(local, buf, (count > sizeof(local)) ? sizeof(local) : count)) { local[11] = 0; WIFI_INFO_FUNC("WIFI_write %s\n", local); if (local[0] == '0') { if (powered == 0) { WIFI_INFO_FUNC("WIFI is already power off!\n"); retval = count; wlan_mode = WLAN_MODE_HALT; goto done; } netdev = dev_get_by_name(&init_net, ifname); if (netdev == NULL) { WIFI_ERR_FUNC("Fail to get %s net device\n", ifname); } else { p2pmode.u4Enable = 0; p2pmode.u4Mode = 0; if (pf_set_p2p_mode) { if (pf_set_p2p_mode(netdev, p2pmode) != 0){ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); } else { WIFI_INFO_FUNC("Turn off p2p/ap mode"); wlan_mode = WLAN_MODE_HALT; } } dev_put(netdev); netdev = NULL; } if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn off WIFI fail!\n"); powered = 2; } else { WIFI_INFO_FUNC("WMT turn off WIFI OK!\n"); powered = 0; retval = count; wlan_mode = WLAN_MODE_HALT; #if CFG_TC1_FEATURE ifname = WLAN_IFACE_NAME; wlan_if_changed = 0; #endif } } else if (local[0] == '1') { if (powered == 1) { WIFI_INFO_FUNC("WIFI is already power on!\n"); retval = count; goto done; } else if (powered == 2) { /* workaround for wifi turn off fail. otherwise, will KE in register_netdevice with wrong dev->state */ WIFI_ERR_FUNC("WIFI turn off fail last time, can't turn on again!\n"); goto done; } if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); } else { powered = 1; retval = count; WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); wlan_mode = WLAN_MODE_HALT; } } else if (local[0] == 'D') { INT32 k = 0; /* * 0: no debug * 1: common debug output * 2: more detials * 3: verbose */ switch (local[1]) { case '0': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = 0; } if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; case '1': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = DBG_CLASS_ERROR | \ DBG_CLASS_WARN | \ DBG_CLASS_STATE | \ DBG_CLASS_EVENT | \ DBG_CLASS_TRACE | \ DBG_CLASS_INFO; } wlan_dbg_level[DBG_TX_IDX] &= ~(DBG_CLASS_EVENT | \ DBG_CLASS_TRACE | \ DBG_CLASS_INFO); wlan_dbg_level[DBG_RX_IDX] &= ~(DBG_CLASS_EVENT | \ DBG_CLASS_TRACE | \ DBG_CLASS_INFO); wlan_dbg_level[DBG_REQ_IDX] &= ~(DBG_CLASS_EVENT | \ DBG_CLASS_TRACE | \ DBG_CLASS_INFO); wlan_dbg_level[DBG_INTR_IDX] = 0; wlan_dbg_level[DBG_MEM_IDX] = 0; if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; case '2': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = DBG_CLASS_ERROR | \ DBG_CLASS_WARN | \ DBG_CLASS_STATE | \ DBG_CLASS_EVENT | \ DBG_CLASS_TRACE | \ DBG_CLASS_INFO; } wlan_dbg_level[DBG_INTR_IDX] = 0; wlan_dbg_level[DBG_MEM_IDX] = 0; if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; case '3': for (k = 0; k < DBG_MODULE_NUM; k++) { wlan_dbg_level[k] = DBG_CLASS_ERROR | \ DBG_CLASS_WARN | \ DBG_CLASS_STATE | \ DBG_CLASS_EVENT | \ DBG_CLASS_TRACE | \ DBG_CLASS_INFO | \ DBG_CLASS_LOUD; } if (pf_set_dbg_level) { pf_set_dbg_level(wlan_dbg_level); } break; default: break; } } else if (local[0] == 'S' || local[0] == 'P' || local[0] == 'A') { if (powered == 2) { /* workaround for wifi turn off fail. otherwise, will KE in register_netdevice with wrong dev->state */ WIFI_ERR_FUNC("WIFI turn off fail last time, can't turn on again!\n"); goto done; } if (powered == 0) { /* If WIFI is off, turn on WIFI first */ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_WIFI)) { WIFI_ERR_FUNC("WMT turn on WIFI fail!\n"); goto done; } else { powered = 1; WIFI_INFO_FUNC("WMT turn on WIFI success!\n"); wlan_mode = WLAN_MODE_HALT; } } if (pf_set_p2p_mode == NULL) { WIFI_ERR_FUNC("Set p2p mode handler is NULL\n"); goto done; } netdev = dev_get_by_name(&init_net, ifname); while (netdev == NULL && wait_cnt < 10) { WIFI_ERR_FUNC("Fail to get %s net device, sleep 300ms\n", ifname); msleep(300); wait_cnt ++; netdev = dev_get_by_name(&init_net, ifname); } if (wait_cnt >= 10) { WIFI_ERR_FUNC("Get %s net device timeout\n", ifname); goto done; } if ((wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'S' || local[0] == 'P')) || (wlan_mode == WLAN_MODE_AP && (local[0] == 'A'))){ WIFI_INFO_FUNC("WIFI is already in mode %d!\n", wlan_mode); retval = count; goto done; } if ((wlan_mode == WLAN_MODE_AP && (local[0] == 'S' || local[0] == 'P')) || (wlan_mode == WLAN_MODE_STA_P2P && (local[0] == 'A'))){ p2pmode.u4Enable = 0; p2pmode.u4Mode = 0; if (pf_set_p2p_mode(netdev, p2pmode) != 0){ WIFI_ERR_FUNC("Turn off p2p/ap mode fail"); goto done; } } if (local[0] == 'S' || local[0] == 'P'){ #if CFG_TC1_FEATURE /* Restore NIC name to wlan0 */ rtnl_lock(); if (strcmp(ifname, WLAN_IFACE_NAME) != 0){ if (dev_change_name(netdev, WLAN_IFACE_NAME) != 0){ WIFI_ERR_FUNC("netdev name change to %s fail\n", WLAN_IFACE_NAME); rtnl_unlock(); goto done; } else{ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, WLAN_IFACE_NAME); ifname = WLAN_IFACE_NAME; wlan_if_changed = 0; } } rtnl_unlock(); #endif p2pmode.u4Enable = 1; p2pmode.u4Mode = 0; if (pf_set_p2p_mode(netdev, p2pmode) != 0){ WIFI_ERR_FUNC("Set wlan mode fail\n"); } else{ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_STA_P2P); wlan_mode = WLAN_MODE_STA_P2P; retval = count; } } else if (local[0] == 'A'){ #if CFG_TC1_FEATURE /* Change NIC name to legacy0, since wlan0 is used for AP */ rtnl_lock(); if (strcmp(ifname, LEGACY_IFACE_NAME) != 0){ if (dev_change_name(netdev, LEGACY_IFACE_NAME) != 0){ WIFI_ERR_FUNC("netdev name change to %s fail\n", LEGACY_IFACE_NAME); rtnl_unlock(); goto done; } else{ WIFI_INFO_FUNC("netdev name changed %s --> %s\n", ifname, LEGACY_IFACE_NAME); ifname = LEGACY_IFACE_NAME; wlan_if_changed = 1; } } rtnl_unlock(); #endif p2pmode.u4Enable = 1; p2pmode.u4Mode = 1; if (pf_set_p2p_mode(netdev, p2pmode) != 0){ WIFI_ERR_FUNC("Set wlan mode fail\n"); } else{ WIFI_INFO_FUNC("Set wlan mode %d --> %d\n", wlan_mode, WLAN_MODE_AP); wlan_mode = WLAN_MODE_AP; retval = count; } } dev_put(netdev); netdev = NULL; } } done: if (netdev != NULL){ dev_put(netdev); } up(&wr_mtx); return (retval); }