⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2o_lan.c

📁 移植到2410开发板上的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct i2o_controller *iop = i2o_dev->controller;	struct dev_mc_list *mc;	u32 msg[10 + 2 * dev->mc_count]; 	u8 *work8 = (u8 *)(msg + 10);	msg[0] = I2O_MESSAGE_SIZE(10 + 2 * dev->mc_count) | SGL_OFFSET_5;	msg[1] = I2O_CMD_UTIL_PARAMS_SET << 24 | HOST_TID << 12 | i2o_dev->lct_data.tid;	msg[2] = priv->unit << 16 | lan_context;	// InitiatorContext	msg[3] = 0x0002 << 16 | (u16)-1;		// TransactionContext	msg[4] = 0;					// OperationFlags	msg[5] = 0xCC000000 | (16 + 8 * dev->mc_count);	// Immediate data SGL	msg[6] = 2;					// OperationCount	msg[7] = 0x0002 << 16 | I2O_PARAMS_TABLE_CLEAR;	// Group, Operation	msg[8] = 0x0002 << 16 | I2O_PARAMS_ROW_ADD;     // Group, Operation	msg[9] = dev->mc_count << 16 | (u16)-1; 	// RowCount, FieldCount        for (mc = dev->mc_list; mc ; mc = mc->next, work8 += 8) {		  memset(work8, 0, 8);                  memcpy(work8, mc->dmi_addr, mc->dmi_addrlen); // Values	}	return i2o_post_this(iop, msg, sizeof(msg));}/* * i2o_lan_set_multicast_list(): Enable a network device to receive packets *      not send to the protocol address. */static void i2o_lan_set_multicast_list(struct net_device *dev){	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	u32 filter_mask;	if (dev->flags & IFF_PROMISC) {		filter_mask = 0x00000002;		dprintk(KERN_INFO "%s: Enabling promiscuous mode...\n", dev->name);	} else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > priv->max_size_mc_table) {		filter_mask = 0x00000004;		dprintk(KERN_INFO "%s: Enabling all multicast mode...\n", dev->name);	} else if (dev->mc_count) {		filter_mask = 0x00000000;		dprintk(KERN_INFO "%s: Enabling multicast mode...\n", dev->name);		if (i2o_lan_set_mc_table(dev) < 0)			printk(KERN_WARNING "%s: Unable to send MAC table.\n", dev->name);	} else {		filter_mask = 0x00000300; // Broadcast, Multicast disabled		dprintk(KERN_INFO "%s: Enabling unicast mode...\n", dev->name);	}	/* Finally copy new FilterMask to DDM */	if (i2o_lan_set_mc_filter(dev, filter_mask) < 0)		printk(KERN_WARNING "%s: Unable to send MAC FilterMask.\n", dev->name);}/* * i2o_lan_change_mtu(): Change maximum transfer unit size. */static int i2o_lan_change_mtu(struct net_device *dev, int new_mtu){	struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;	struct i2o_device *i2o_dev = priv->i2o_dev;	u32 max_pkt_size;	if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,		 	     0x0000, 6, &max_pkt_size, 4) < 0)		return -EFAULT;	if (new_mtu < 68 || new_mtu > 9000 || new_mtu > max_pkt_size)		return -EINVAL;	dev->mtu = new_mtu;	i2o_lan_suspend(dev);   	// to SUSPENDED state, return buckets	while (priv->i2o_fbl_tail >= 0) // free buffered buckets		dev_kfree_skb(priv->i2o_fbl[priv->i2o_fbl_tail--]);	i2o_lan_reset(dev);		// to OPERATIONAL state	i2o_set_ddm_parameters(dev); 	// reset some parameters	i2o_lan_receive_post(dev); 	// post new buckets (new size)	return 0;}/* Functions to initialize I2O LAN OSM:======================================*//* * i2o_lan_register_device(): Register LAN class device to kernel. */struct net_device *i2o_lan_register_device(struct i2o_device *i2o_dev){	struct net_device *dev = NULL;	struct i2o_lan_local *priv = NULL;	u8 hw_addr[8];	u32 tx_max_out = 0;	unsigned short (*type_trans)(struct sk_buff *, struct net_device *);	void (*unregister_dev)(struct net_device *dev);	switch (i2o_dev->lct_data.sub_class) {	case I2O_LAN_ETHERNET:		dev = init_etherdev(NULL, sizeof(struct i2o_lan_local));		if (dev == NULL)			return NULL;		type_trans = eth_type_trans;		unregister_dev = unregister_netdev;		break;#ifdef CONFIG_ANYLAN	case I2O_LAN_100VG:		printk(KERN_ERR "i2o_lan: 100base VG not yet supported.\n");		return NULL;		break;#endif#ifdef CONFIG_TR	case I2O_LAN_TR:		dev = init_trdev(NULL, sizeof(struct i2o_lan_local));		if (dev==NULL)			return NULL;		type_trans = tr_type_trans;		unregister_dev = unregister_trdev;		break;#endif#ifdef CONFIG_FDDI	case I2O_LAN_FDDI:	{		int size = sizeof(struct net_device) + sizeof(struct i2o_lan_local);		dev = (struct net_device *) kmalloc(size, GFP_KERNEL);		if (dev == NULL)			return NULL;		memset((char *)dev, 0, size);	    	dev->priv = (void *)(dev + 1);		if (dev_alloc_name(dev, "fddi%d") < 0) {			printk(KERN_WARNING "i2o_lan: Too many FDDI devices.\n");			kfree(dev);			return NULL;		}		type_trans = fddi_type_trans;		unregister_dev = (void *)unregister_netdevice;		fddi_setup(dev);		register_netdev(dev);	}	break;#endif#ifdef CONFIG_NET_FC	case I2O_LAN_FIBRE_CHANNEL:		dev = init_fcdev(NULL, sizeof(struct i2o_lan_local));		if (dev == NULL)			return NULL;		type_trans = NULL;/* FIXME: Move fc_type_trans() from drivers/net/fc/iph5526.c to net/802/fc.c * and export it in include/linux/fcdevice.h *		type_trans = fc_type_trans; */		unregister_dev = (void *)unregister_fcdev;		break;#endif	case I2O_LAN_UNKNOWN:	default:		printk(KERN_ERR "i2o_lan: LAN type 0x%04x not supported.\n",		       i2o_dev->lct_data.sub_class);		return NULL;	}	priv = (struct i2o_lan_local *)dev->priv;	priv->i2o_dev = i2o_dev;	priv->type_trans = type_trans;	priv->sgl_max = (i2o_dev->controller->status_block->inbound_frame_size - 4) / 3;	atomic_set(&priv->buckets_out, 0);	/* Set default values for user configurable parameters */	/* Private values are changed via /proc file system */	priv->max_buckets_out = max_buckets_out;	priv->bucket_thresh   = bucket_thresh;	priv->rx_copybreak    = rx_copybreak;	priv->tx_batch_mode   = tx_batch_mode & 0x03;	priv->i2o_event_mask  = i2o_event_mask;	priv->tx_lock	      = SPIN_LOCK_UNLOCKED;	priv->fbl_lock	      = SPIN_LOCK_UNLOCKED;	unit++;	i2o_landevs[unit] = dev;	priv->unit = unit;	if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,			     0x0001, 0, &hw_addr, sizeof(hw_addr)) < 0) {		printk(KERN_ERR "%s: Unable to query hardware address.\n", dev->name);		unit--;		unregister_dev(dev);		kfree(dev);		return NULL;	}	dprintk(KERN_DEBUG "%s: hwaddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 		dev->name, hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3],		hw_addr[4], hw_addr[5]);	dev->addr_len = 6;	memcpy(dev->dev_addr, hw_addr, 6);	if (i2o_query_scalar(i2o_dev->controller, i2o_dev->lct_data.tid,			     0x0007, 2, &tx_max_out, sizeof(tx_max_out)) < 0) {		printk(KERN_ERR "%s: Unable to query max TX queue.\n", dev->name);		unit--;		unregister_dev(dev);		kfree(dev);		return NULL;	}	dprintk(KERN_INFO "%s: Max TX Outstanding = %d.\n", dev->name, tx_max_out);	priv->tx_max_out = tx_max_out;	atomic_set(&priv->tx_out, 0);	priv->tx_count = 0;	INIT_LIST_HEAD(&priv->i2o_batch_send_task.list);	priv->i2o_batch_send_task.sync    = 0;	priv->i2o_batch_send_task.routine = (void *)i2o_lan_batch_send;	priv->i2o_batch_send_task.data    = (void *)dev;	dev->open		= i2o_lan_open;	dev->stop		= i2o_lan_close;	dev->get_stats		= i2o_lan_get_stats;	dev->set_multicast_list = i2o_lan_set_multicast_list;	dev->tx_timeout		= i2o_lan_tx_timeout;	dev->watchdog_timeo	= I2O_LAN_TX_TIMEOUT;#ifdef CONFIG_NET_FC	if (i2o_dev->lct_data.sub_class == I2O_LAN_FIBRE_CHANNEL)		dev->hard_start_xmit = i2o_lan_sdu_send;	else#endif		dev->hard_start_xmit = i2o_lan_packet_send;	if (i2o_dev->lct_data.sub_class == I2O_LAN_ETHERNET)		dev->change_mtu	= i2o_lan_change_mtu;	return dev;}#ifdef MODULE#define i2o_lan_init	init_module#endifint __init i2o_lan_init(void){	struct net_device *dev;	int i;	printk(KERN_INFO "I2O LAN OSM (C) 1999 University of Helsinki.\n");	/* Module params are used as global defaults for private values */	if (max_buckets_out > I2O_LAN_MAX_BUCKETS_OUT)		max_buckets_out = I2O_LAN_MAX_BUCKETS_OUT;	if (bucket_thresh > max_buckets_out)		bucket_thresh = max_buckets_out;	/* Install handlers for incoming replies */	if (i2o_install_handler(&i2o_lan_send_handler) < 0) { 		printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");		return -EINVAL;	}	lan_send_context = i2o_lan_send_handler.context;	if (i2o_install_handler(&i2o_lan_receive_handler) < 0) { 		printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");		return -EINVAL;	}	lan_receive_context = i2o_lan_receive_handler.context;	if (i2o_install_handler(&i2o_lan_handler) < 0) { 		printk(KERN_ERR "i2o_lan: Unable to register I2O LAN OSM.\n");		return -EINVAL;	}	lan_context = i2o_lan_handler.context;	for(i=0; i <= MAX_LAN_CARDS; i++)		i2o_landevs[i] = NULL;	for (i=0; i < MAX_I2O_CONTROLLERS; i++) {		struct i2o_controller *iop = i2o_find_controller(i);		struct i2o_device *i2o_dev;		if (iop==NULL)			continue;		for (i2o_dev=iop->devices;i2o_dev != NULL;i2o_dev=i2o_dev->next) {			if (i2o_dev->lct_data.class_id != I2O_CLASS_LAN)				continue;			/* Make sure device not already claimed by an ISM */			if (i2o_dev->lct_data.user_tid != 0xFFF)				continue;			if (unit == MAX_LAN_CARDS) {				i2o_unlock_controller(iop);				printk(KERN_WARNING "i2o_lan: Too many I2O LAN devices.\n");				return -EINVAL;			}			dev = i2o_lan_register_device(i2o_dev); 			if (dev == NULL) {				printk(KERN_ERR "i2o_lan: Unable to register I2O LAN device 0x%04x.\n",				       i2o_dev->lct_data.sub_class);				continue;			}			printk(KERN_INFO "%s: I2O LAN device registered, "				"subclass = 0x%04x, unit = %d, tid = %d.\n",				dev->name, i2o_dev->lct_data.sub_class,				((struct i2o_lan_local *)dev->priv)->unit,				i2o_dev->lct_data.tid);		}		i2o_unlock_controller(iop);	}	dprintk(KERN_INFO "%d I2O LAN devices found and registered.\n", unit+1);	return 0;}#ifdef MODULEvoid cleanup_module(void){	int i;	for (i = 0; i <= unit; i++) {		struct net_device *dev = i2o_landevs[i];		struct i2o_lan_local *priv = (struct i2o_lan_local *)dev->priv;		struct i2o_device *i2o_dev = priv->i2o_dev;		switch (i2o_dev->lct_data.sub_class) {		case I2O_LAN_ETHERNET:			unregister_netdev(dev);			break;#ifdef CONFIG_FDDI		case I2O_LAN_FDDI:			unregister_netdevice(dev);			break;#endif#ifdef CONFIG_TR		case I2O_LAN_TR:			unregister_trdev(dev);			break;#endif#ifdef CONFIG_NET_FC		case I2O_LAN_FIBRE_CHANNEL:			unregister_fcdev(dev);			break;#endif		default:			printk(KERN_WARNING "%s: Spurious I2O LAN subclass 0x%08x.\n",			       dev->name, i2o_dev->lct_data.sub_class);		}		dprintk(KERN_INFO "%s: I2O LAN device unregistered.\n",			dev->name);		kfree(dev);	}	i2o_remove_handler(&i2o_lan_handler);	i2o_remove_handler(&i2o_lan_send_handler);	i2o_remove_handler(&i2o_lan_receive_handler);}EXPORT_NO_SYMBOLS;MODULE_AUTHOR("University of Helsinki, Department of Computer Science");MODULE_DESCRIPTION("I2O Lan OSM");MODULE_LICENSE("GPL");MODULE_PARM(max_buckets_out, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");MODULE_PARM_DESC(max_buckets_out, "Total number of buckets to post (1-)");MODULE_PARM(bucket_thresh, "1-" __MODULE_STRING(I2O_LAN_MAX_BUCKETS_OUT) "i");MODULE_PARM_DESC(bucket_thresh, "Bucket post threshold (1-)");MODULE_PARM(rx_copybreak, "1-" "i");MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy only small frames (1-)");MODULE_PARM(tx_batch_mode, "0-2" "i");MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically");#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -