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

📄 e1000_main.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
			continue;		}		if(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK) {			last_byte = *(skb->data + length - 1);			if(TBI_ACCEPT(&adapter->hw, rx_desc->status,			              rx_desc->errors, length, last_byte)) {				spin_lock_irqsave(&adapter->stats_lock, flags);				e1000_tbi_adjust_stats(&adapter->hw,				                       &adapter->stats,				                       length, skb->data);				spin_unlock_irqrestore(&adapter->stats_lock,				                       flags);				length--;			} else {				dev_kfree_skb_irq(skb);				rx_desc->status = 0;				rx_ring->buffer_info[i].skb = NULL;				i = (i + 1) % rx_ring->count;				rx_desc = E1000_RX_DESC(*rx_ring, i);				continue;			}		}		/* Good Receive */		skb_put(skb, length - ETHERNET_FCS_SIZE);		/* Receive Checksum Offload */		e1000_rx_checksum(adapter, rx_desc, skb);		skb->protocol = eth_type_trans(skb, netdev);		if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) {			vlan_hwaccel_rx(skb, adapter->vlgrp,				(rx_desc->special & E1000_RXD_SPC_VLAN_MASK));		} else {			netif_rx(skb);		}		netdev->last_rx = jiffies;		rx_desc->status = 0;		rx_ring->buffer_info[i].skb = NULL;		i = (i + 1) % rx_ring->count;		rx_desc = E1000_RX_DESC(*rx_ring, i);	}	rx_ring->next_to_clean = i;	e1000_alloc_rx_buffers(adapter);}/** * e1000_alloc_rx_buffers - Replace used receive buffers * @data: address of board private structure **/static voide1000_alloc_rx_buffers(struct e1000_adapter *adapter){	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;	struct net_device *netdev = adapter->netdev;	struct pci_dev *pdev = adapter->pdev;	struct e1000_rx_desc *rx_desc;	struct sk_buff *skb;	int reserve_len;	int i;	reserve_len = 2;	i = rx_ring->next_to_use;	while(!rx_ring->buffer_info[i].skb) {		rx_desc = E1000_RX_DESC(*rx_ring, i);		skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len);		if(!skb) {			/* Better luck next round */			break;		}		/* Make buffer alignment 2 beyond a 16 byte boundary		 * this will result in a 16 byte aligned IP header after		 * the 14 byte MAC header is removed		 */		skb_reserve(skb, reserve_len);		skb->dev = netdev;		rx_ring->buffer_info[i].skb = skb;		rx_ring->buffer_info[i].length = adapter->rx_buffer_len;		rx_ring->buffer_info[i].dma =			pci_map_single(pdev,			               skb->data,			               adapter->rx_buffer_len,			               PCI_DMA_FROMDEVICE);		rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma);		if(!(i % E1000_RX_BUFFER_WRITE)) {			/* Force memory writes to complete before letting h/w			 * know there are new descriptors to fetch.  (Only			 * applicable for weak-ordered memory model archs,			 * such as IA-64). */			wmb();			E1000_WRITE_REG(&adapter->hw, RDT, i);		}		i = (i + 1) % rx_ring->count;	}	rx_ring->next_to_use = i;}/** * e1000_ioctl - * @netdev: * @ifreq: * @cmd: **/static inte1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd){	switch (cmd) {	case SIOCETHTOOL:		return e1000_ethtool_ioctl(netdev, ifr);	default:		return -EOPNOTSUPP;	}}/** * e1000_rx_checksum - Receive Checksum Offload for 82543 * @adapter: board private structure * @rx_desc: receive descriptor * @sk_buff: socket buffer with received data **/static inline voide1000_rx_checksum(struct e1000_adapter *adapter,                  struct e1000_rx_desc *rx_desc,                  struct sk_buff *skb){	/* 82543 or newer only */	if((adapter->hw.mac_type < e1000_82543) ||	/* Ignore Checksum bit is set */	(rx_desc->status & E1000_RXD_STAT_IXSM) ||	/* TCP Checksum has not been calculated */	(!(rx_desc->status & E1000_RXD_STAT_TCPCS))) {		skb->ip_summed = CHECKSUM_NONE;		return;	}	/* At this point we know the hardware did the TCP checksum */	/* now look at the TCP checksum error bit */	if(rx_desc->errors & E1000_RXD_ERR_TCPE) {		/* let the stack verify checksum errors */		skb->ip_summed = CHECKSUM_NONE;		adapter->hw_csum_err++;	} else {	/* TCP checksum is good */		skb->ip_summed = CHECKSUM_UNNECESSARY;		adapter->hw_csum_good++;	}}voide1000_pci_set_mwi(struct e1000_hw *hw){	struct e1000_adapter *adapter = hw->back;	pci_set_mwi(adapter->pdev);}voide1000_pci_clear_mwi(struct e1000_hw *hw){	struct e1000_adapter *adapter = hw->back;	pci_clear_mwi(adapter->pdev);}voide1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value){	struct e1000_adapter *adapter = hw->back;	pci_read_config_word(adapter->pdev, reg, value);}voide1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value){	struct e1000_adapter *adapter = hw->back;	pci_write_config_word(adapter->pdev, reg, *value);}uint32_te1000_io_read(struct e1000_hw *hw, uint32_t port){	return inl(port);}voide1000_io_write(struct e1000_hw *hw, uint32_t port, uint32_t value){	outl(value, port);}static voide1000_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp){	struct e1000_adapter *adapter = netdev->priv;	uint32_t ctrl, rctl;	e1000_irq_disable(adapter);	adapter->vlgrp = grp;	if(grp) {		/* enable VLAN tag insert/strip */		E1000_WRITE_REG(&adapter->hw, VET, ETHERNET_IEEE_VLAN_TYPE);		ctrl = E1000_READ_REG(&adapter->hw, CTRL);		ctrl |= E1000_CTRL_VME;		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);		/* enable VLAN receive filtering */		rctl = E1000_READ_REG(&adapter->hw, RCTL);		rctl |= E1000_RCTL_VFE;		rctl &= ~E1000_RCTL_CFIEN;		E1000_WRITE_REG(&adapter->hw, RCTL, rctl);	} else {		/* disable VLAN tag insert/strip */		ctrl = E1000_READ_REG(&adapter->hw, CTRL);		ctrl &= ~E1000_CTRL_VME;		E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);		/* disable VLAN filtering */		rctl = E1000_READ_REG(&adapter->hw, RCTL);		rctl &= ~E1000_RCTL_VFE;		E1000_WRITE_REG(&adapter->hw, RCTL, rctl);	}	e1000_irq_enable(adapter);}static voide1000_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid){	struct e1000_adapter *adapter = netdev->priv;	uint32_t vfta, index;	/* add VID to filter table */	index = (vid >> 5) & 0x7F;	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);	vfta |= (1 << (vid & 0x1F));	e1000_write_vfta(&adapter->hw, index, vfta);}static voide1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid){	struct e1000_adapter *adapter = netdev->priv;	uint32_t vfta, index;	e1000_irq_disable(adapter);	if(adapter->vlgrp)		adapter->vlgrp->vlan_devices[vid] = NULL;	e1000_irq_enable(adapter);	/* remove VID from filter table*/	index = (vid >> 5) & 0x7F;	vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index);	vfta &= ~(1 << (vid & 0x1F));	e1000_write_vfta(&adapter->hw, index, vfta);}static voide1000_restore_vlan(struct e1000_adapter *adapter){	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);	if(adapter->vlgrp) {		uint16_t vid;		for(vid = 0; vid < VLAN_GROUP_ARRAY_LEN; vid++) {			if(!adapter->vlgrp->vlan_devices[vid])				continue;			e1000_vlan_rx_add_vid(adapter->netdev, vid);		}	}}static inte1000_notify_reboot(struct notifier_block *nb, unsigned long event, void *p){	struct pci_dev *pdev = NULL;	switch(event) {	case SYS_DOWN:	case SYS_HALT:	case SYS_POWER_OFF:		pci_for_each_dev(pdev) {			if(pci_dev_driver(pdev) == &e1000_driver)				e1000_suspend(pdev, 3);		}	}	return NOTIFY_DONE;}static inte1000_notify_netdev(struct notifier_block *nb, unsigned long event, void *p){	struct e1000_adapter *adapter;	struct net_device *netdev = p;	if(netdev == NULL)		return NOTIFY_DONE;	switch(event) {	case NETDEV_CHANGENAME:		if(netdev->open == e1000_open) {			adapter = netdev->priv;			/* rename the proc nodes the easy way */			e1000_proc_dev_free(adapter);			memcpy(adapter->ifname, netdev->name, IFNAMSIZ);			adapter->ifname[IFNAMSIZ-1] = 0;			e1000_proc_dev_setup(adapter);		}		break;	}	return NOTIFY_DONE;}static inte1000_suspend(struct pci_dev *pdev, uint32_t state){	struct net_device *netdev = pci_get_drvdata(pdev);	struct e1000_adapter *adapter = netdev->priv;	uint32_t ctrl, ctrl_ext, rctl, manc, status;	uint32_t wufc = adapter->wol;	netif_device_detach(netdev);	if(netif_running(netdev))		e1000_down(adapter);	status = E1000_READ_REG(&adapter->hw, STATUS);	if(status & E1000_STATUS_LU)		wufc &= ~E1000_WUFC_LNKC;	if(wufc) {		e1000_setup_rctl(adapter);		e1000_set_multi(netdev);		/* turn on all-multi mode if wake on multicast is enabled */		if(adapter->wol & E1000_WUFC_MC) {			rctl = E1000_READ_REG(&adapter->hw, RCTL);			rctl |= E1000_RCTL_MPE;			E1000_WRITE_REG(&adapter->hw, RCTL, rctl);		}		if(adapter->hw.mac_type >= e1000_82540) {			ctrl = E1000_READ_REG(&adapter->hw, CTRL);			/* advertise wake from D3Cold */			#define E1000_CTRL_ADVD3WUC 0x00100000			/* phy power management enable */			#define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000			ctrl |= E1000_CTRL_ADVD3WUC |				E1000_CTRL_EN_PHY_PWR_MGMT;			E1000_WRITE_REG(&adapter->hw, CTRL, ctrl);		}		if(adapter->hw.media_type == e1000_media_type_fiber) {			/* keep the laser running in D3 */			ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;			E1000_WRITE_REG(&adapter->hw, CTRL_EXT, ctrl_ext);		}		E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN);		E1000_WRITE_REG(&adapter->hw, WUFC, wufc);		pci_enable_wake(pdev, 3, 1);		pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */	} else {		E1000_WRITE_REG(&adapter->hw, WUC, 0);		E1000_WRITE_REG(&adapter->hw, WUFC, 0);		pci_enable_wake(pdev, 3, 0);		pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */	}	pci_save_state(pdev, adapter->pci_state);	if(adapter->hw.mac_type >= e1000_82540) {		manc = E1000_READ_REG(&adapter->hw, MANC);		if(manc & E1000_MANC_SMBUS_EN) {			manc |= E1000_MANC_ARP_EN;			E1000_WRITE_REG(&adapter->hw, MANC, manc);			state = 0;		}	}	state = (state > 0) ? 3 : 0;	pci_set_power_state(pdev, state);	return 0;}#ifdef CONFIG_PMstatic inte1000_resume(struct pci_dev *pdev){	struct net_device *netdev = pci_get_drvdata(pdev);	struct e1000_adapter *adapter = netdev->priv;	uint32_t manc;	pci_set_power_state(pdev, 0);	pci_restore_state(pdev, adapter->pci_state);	pci_enable_wake(pdev, 3, 0);	pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */	e1000_reset(adapter);	E1000_WRITE_REG(&adapter->hw, WUS, ~0);	if(netif_running(netdev))		e1000_up(adapter);	netif_device_attach(netdev);	if(adapter->hw.mac_type >= e1000_82540) {		manc = E1000_READ_REG(&adapter->hw, MANC);		manc &= ~(E1000_MANC_ARP_EN);		E1000_WRITE_REG(&adapter->hw, MANC, manc);	}	return 0;}#endif/* e1000_main.c */

⌨️ 快捷键说明

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