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

📄 e1000_mac.c

📁 e1000 8.0.1 version.最新的e1000 linux下的驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************  Intel PRO/1000 Linux driver  Copyright(c) 1999 - 2008 Intel Corporation.  This program is free software; you can redistribute it and/or modify it  under the terms and conditions of the GNU General Public License,  version 2, as published by the Free Software Foundation.  This program is distributed in the hope it will be useful, but WITHOUT  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for  more details.  You should have received a copy of the GNU General Public License along with  this program; if not, write to the Free Software Foundation, Inc.,  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.  The full GNU General Public License is included in this distribution in  the file called "COPYING".  Contact Information:  Linux NICS <linux.nics@intel.com>  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497*******************************************************************************/#include "e1000_api.h"#include "e1000_mac.h"/** *  e1000_init_mac_ops_generic - Initialize MAC function pointers *  @hw: pointer to the HW structure * *  Setups up the function pointers to no-op functions **/void e1000_init_mac_ops_generic(struct e1000_hw *hw){	struct e1000_mac_info *mac = &hw->mac;	DEBUGFUNC("e1000_init_mac_ops_generic");	/* General Setup */	mac->ops.init_params = e1000_null_ops_generic;	mac->ops.init_hw = e1000_null_ops_generic;	mac->ops.reset_hw = e1000_null_ops_generic;	mac->ops.setup_physical_interface = e1000_null_ops_generic;	mac->ops.get_bus_info = e1000_null_ops_generic;	mac->ops.read_mac_addr = e1000_read_mac_addr_generic;	mac->ops.remove_device = e1000_remove_device_generic;	mac->ops.config_collision_dist = e1000_config_collision_dist_generic;	mac->ops.clear_hw_cntrs = e1000_null_mac_generic;	/* LED */	mac->ops.cleanup_led = e1000_null_ops_generic;	mac->ops.setup_led = e1000_null_ops_generic;	mac->ops.blink_led = e1000_null_ops_generic;	mac->ops.led_on = e1000_null_ops_generic;	mac->ops.led_off = e1000_null_ops_generic;	/* LINK */	mac->ops.setup_link = e1000_null_ops_generic;	mac->ops.get_link_up_info = e1000_null_link_info;	mac->ops.check_for_link = e1000_null_ops_generic;	mac->ops.wait_autoneg = e1000_wait_autoneg_generic;	/* Management */	mac->ops.check_mng_mode = e1000_null_mng_mode;	mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic;	mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic;	mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic;	/* VLAN, MC, etc. */	mac->ops.update_mc_addr_list = e1000_null_update_mc;	mac->ops.clear_vfta = e1000_null_mac_generic;	mac->ops.write_vfta = e1000_null_write_vfta;	mac->ops.mta_set = e1000_null_mta_set;	mac->ops.rar_set = e1000_rar_set_generic;	mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic;}/** *  e1000_null_ops_generic - No-op function, returns 0 *  @hw: pointer to the HW structure **/s32 e1000_null_ops_generic(struct e1000_hw *hw){	DEBUGFUNC("e1000_null_ops_generic");	return E1000_SUCCESS;}/** *  e1000_null_mac_generic - No-op function, return void *  @hw: pointer to the HW structure **/void e1000_null_mac_generic(struct e1000_hw *hw){	DEBUGFUNC("e1000_null_mac_generic");	return;}/** *  e1000_null_link_info - No-op function, return 0 *  @hw: pointer to the HW structure **/s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d){	DEBUGFUNC("e1000_null_link_info");	return E1000_SUCCESS;}/** *  e1000_null_mng_mode - No-op function, return false *  @hw: pointer to the HW structure **/bool e1000_null_mng_mode(struct e1000_hw *hw){	DEBUGFUNC("e1000_null_mng_mode");	return FALSE;}/** *  e1000_null_update_mc - No-op function, return void *  @hw: pointer to the HW structure **/void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c){	DEBUGFUNC("e1000_null_update_mc");	return;}/** *  e1000_null_write_vfta - No-op function, return void *  @hw: pointer to the HW structure **/void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b){	DEBUGFUNC("e1000_null_write_vfta");	return;}/** *  e1000_null_set_mta - No-op function, return void *  @hw: pointer to the HW structure **/void e1000_null_mta_set(struct e1000_hw *hw, u32 a){	DEBUGFUNC("e1000_null_mta_set");	return;}/** *  e1000_null_rar_set - No-op function, return void *  @hw: pointer to the HW structure **/void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a){	DEBUGFUNC("e1000_null_rar_set");	return;}/** *  e1000_remove_device_generic - Free device specific structure *  @hw: pointer to the HW structure * *  If a device specific structure was allocated, this function will *  free it. **/void e1000_remove_device_generic(struct e1000_hw *hw){	DEBUGFUNC("e1000_remove_device_generic");	/* Freeing the dev_spec member of e1000_hw structure */	e1000_free_dev_spec_struct(hw);}/** *  e1000_get_bus_info_pci_generic - Get PCI(x) bus information *  @hw: pointer to the HW structure * *  Determines and stores the system bus information for a particular *  network interface.  The following bus information is determined and stored: *  bus speed, bus width, type (PCI/PCIx), and PCI(-x) function. **/s32 e1000_get_bus_info_pci_generic(struct e1000_hw *hw){	struct e1000_bus_info *bus = &hw->bus;	u32 status = E1000_READ_REG(hw, E1000_STATUS);	s32 ret_val = E1000_SUCCESS;	u16 pci_header_type;	DEBUGFUNC("e1000_get_bus_info_pci_generic");	/* PCI or PCI-X? */	bus->type = (status & E1000_STATUS_PCIX_MODE)			? e1000_bus_type_pcix			: e1000_bus_type_pci;	/* Bus speed */	if (bus->type == e1000_bus_type_pci) {		bus->speed = (status & E1000_STATUS_PCI66)		             ? e1000_bus_speed_66		             : e1000_bus_speed_33;	} else {		switch (status & E1000_STATUS_PCIX_SPEED) {		case E1000_STATUS_PCIX_SPEED_66:			bus->speed = e1000_bus_speed_66;			break;		case E1000_STATUS_PCIX_SPEED_100:			bus->speed = e1000_bus_speed_100;			break;		case E1000_STATUS_PCIX_SPEED_133:			bus->speed = e1000_bus_speed_133;			break;		default:			bus->speed = e1000_bus_speed_reserved;			break;		}	}	/* Bus width */	bus->width = (status & E1000_STATUS_BUS64)	             ? e1000_bus_width_64	             : e1000_bus_width_32;	/* Which PCI(-X) function? */	e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);	if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC)		bus->func = (status & E1000_STATUS_FUNC_MASK)		            >> E1000_STATUS_FUNC_SHIFT;	else		bus->func = 0;	return ret_val;}/** *  e1000_get_bus_info_pcie_generic - Get PCIe bus information *  @hw: pointer to the HW structure * *  Determines and stores the system bus information for a particular *  network interface.  The following bus information is determined and stored: *  bus speed, bus width, type (PCIe), and PCIe function. **/s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw){	struct e1000_bus_info *bus = &hw->bus;	s32 ret_val;	u32 status;	u16 pcie_link_status, pci_header_type;	DEBUGFUNC("e1000_get_bus_info_pcie_generic");	bus->type = e1000_bus_type_pci_express;	bus->speed = e1000_bus_speed_2500;	ret_val = e1000_read_pcie_cap_reg(hw,	                                  PCIE_LINK_STATUS,	                                  &pcie_link_status);	if (ret_val)		bus->width = e1000_bus_width_unknown;	else		bus->width = (e1000_bus_width)((pcie_link_status &		                                PCIE_LINK_WIDTH_MASK) >>		                               PCIE_LINK_WIDTH_SHIFT);	e1000_read_pci_cfg(hw, PCI_HEADER_TYPE_REGISTER, &pci_header_type);	if (pci_header_type & PCI_HEADER_TYPE_MULTIFUNC) {		status = E1000_READ_REG(hw, E1000_STATUS);		bus->func = (status & E1000_STATUS_FUNC_MASK)		            >> E1000_STATUS_FUNC_SHIFT;	} else {		bus->func = 0;	}	return E1000_SUCCESS;}/** *  e1000_clear_vfta_generic - Clear VLAN filter table *  @hw: pointer to the HW structure * *  Clears the register array which contains the VLAN filter table by *  setting all the values to 0. **/void e1000_clear_vfta_generic(struct e1000_hw *hw){	u32 offset;	DEBUGFUNC("e1000_clear_vfta_generic");	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {		E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0);		E1000_WRITE_FLUSH(hw);	}}/** *  e1000_write_vfta_generic - Write value to VLAN filter table *  @hw: pointer to the HW structure *  @offset: register offset in VLAN filter table *  @value: register value written to VLAN filter table * *  Writes value at the given offset in the register array which stores *  the VLAN filter table. **/void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value){	DEBUGFUNC("e1000_write_vfta_generic");	E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value);	E1000_WRITE_FLUSH(hw);}/** *  e1000_init_rx_addrs_generic - Initialize receive address's *  @hw: pointer to the HW structure *  @rar_count: receive address registers * *  Setups the receive address registers by setting the base receive address *  register to the devices MAC address and clearing all the other receive *  address registers to 0. **/void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count){	u32 i;	DEBUGFUNC("e1000_init_rx_addrs_generic");	/* Setup the receive address */	DEBUGOUT("Programming MAC Address into RAR[0]\n");	e1000_rar_set_generic(hw, hw->mac.addr, 0);	/* Zero out the other (rar_entry_count - 1) receive addresses */	DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1);	for (i = 1; i < rar_count; i++) {		E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1), 0);		E1000_WRITE_FLUSH(hw);		E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((i << 1) + 1), 0);		E1000_WRITE_FLUSH(hw);	}}/** *  e1000_check_alt_mac_addr_generic - Check for alternate MAC addr *  @hw: pointer to the HW structure * *  Checks the nvm for an alternate MAC address.  An alternate MAC address *  can be setup by pre-boot software and must be treated like a permanent *  address and must override the actual permanent MAC address.  If an *  alternate MAC address is found it is saved in the hw struct and *  programmed into RAR0 and the function returns success, otherwise the *  function returns an error. **/s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw){	u32 i;	s32 ret_val = E1000_SUCCESS;	u16 offset, nvm_alt_mac_addr_offset, nvm_data;	u8 alt_mac_addr[ETH_ADDR_LEN];	DEBUGFUNC("e1000_check_alt_mac_addr_generic");	ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1,	                         &nvm_alt_mac_addr_offset);	if (ret_val) {		DEBUGOUT("NVM Read Error\n");		goto out;	}	if (nvm_alt_mac_addr_offset == 0xFFFF) {		ret_val = -(E1000_NOT_IMPLEMENTED);		goto out;	}	if (hw->bus.func == E1000_FUNC_1)		nvm_alt_mac_addr_offset += ETH_ADDR_LEN/sizeof(u16);	for (i = 0; i < ETH_ADDR_LEN; i += 2) {		offset = nvm_alt_mac_addr_offset + (i >> 1);		ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data);		if (ret_val) {			DEBUGOUT("NVM Read Error\n");			goto out;		}		alt_mac_addr[i] = (u8)(nvm_data & 0xFF);		alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);	}	/* if multicast bit is set, the alternate address will not be used */	if (alt_mac_addr[0] & 0x01) {		ret_val = -(E1000_NOT_IMPLEMENTED);		goto out;	}	for (i = 0; i < ETH_ADDR_LEN; i++)		hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i];	hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0);out:	return ret_val;}/** *  e1000_rar_set_generic - Set receive address register *  @hw: pointer to the HW structure *  @addr: pointer to the receive address *  @index: receive address array register * *  Sets the receive address array register at index to the address passed *  in by addr. **/void e1000_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index){	u32 rar_low, rar_high;	DEBUGFUNC("e1000_rar_set_generic");	/*	 * HW expects these in little endian so we reverse the byte order	 * from network order (big endian) to little endian	 */	rar_low = ((u32) addr[0] |	           ((u32) addr[1] << 8) |	           ((u32) addr[2] << 16) | ((u32) addr[3] << 24));	rar_high = ((u32) addr[4] | ((u32) addr[5] << 8));	/* If MAC address zero, no need to set the AV bit */	if (rar_low || rar_high) {		if (!hw->mac.disable_av)			rar_high |= E1000_RAH_AV;	}	E1000_WRITE_REG(hw, E1000_RAL(index), rar_low);

⌨️ 快捷键说明

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