Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
/*****************************************************************************
 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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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;
}
Esempio n. 12
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;
	}
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
/*-----------------------------------------------------------------*/
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;
}
Esempio n. 19
0
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;
}
Esempio n. 21
0
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;
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
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;
}
Esempio n. 25
0
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;
}
Esempio n. 26
0
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);
}