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

📄 ixgbe_common.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return status;}/** *  ixgbe_poll_eeprom_eerd_done - Poll EERD status *  @hw: pointer to hardware structure * *  Polls the status bit (bit 1) of the EERD to determine when the read is done. **/static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw){	u32 i;	u32 reg;	s32 status = IXGBE_ERR_EEPROM;	for (i = 0; i < IXGBE_EERD_ATTEMPTS; i++) {		reg = IXGBE_READ_REG(hw, IXGBE_EERD);		if (reg & IXGBE_EEPROM_READ_REG_DONE) {			status = 0;			break;		}		udelay(5);	}	return status;}/** *  ixgbe_get_eeprom_semaphore - Get hardware semaphore *  @hw: pointer to hardware structure * *  Sets the hardware semaphores so EEPROM access can occur for bit-bang method **/static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw){	s32 status = IXGBE_ERR_EEPROM;	u32 timeout;	u32 i;	u32 swsm;	/* Set timeout value based on size of EEPROM */	timeout = hw->eeprom.word_size + 1;	/* Get SMBI software semaphore between device drivers first */	for (i = 0; i < timeout; i++) {		/*		 * If the SMBI bit is 0 when we read it, then the bit will be		 * set and we have the semaphore		 */		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);		if (!(swsm & IXGBE_SWSM_SMBI)) {			status = 0;			break;		}		msleep(1);	}	/* Now get the semaphore between SW/FW through the SWESMBI bit */	if (status == 0) {		for (i = 0; i < timeout; i++) {			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);			/* Set the SW EEPROM semaphore bit to request access */			swsm |= IXGBE_SWSM_SWESMBI;			IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);			/*			 * If we set the bit successfully then we got the			 * semaphore.			 */			swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);			if (swsm & IXGBE_SWSM_SWESMBI)				break;			udelay(50);		}		/*		 * Release semaphores and return error if SW EEPROM semaphore		 * was not granted because we don't have access to the EEPROM		 */		if (i >= timeout) {			hw_dbg(hw, "Driver can't access the Eeprom - Semaphore "				 "not granted.\n");			ixgbe_release_eeprom_semaphore(hw);			status = IXGBE_ERR_EEPROM;		}	}	return status;}/** *  ixgbe_release_eeprom_semaphore - Release hardware semaphore *  @hw: pointer to hardware structure * *  This function clears hardware semaphore bits. **/static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw){	u32 swsm;	swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);	/* Release both semaphores by writing 0 to the bits SWESMBI and SMBI */	swsm &= ~(IXGBE_SWSM_SWESMBI | IXGBE_SWSM_SMBI);	IXGBE_WRITE_REG(hw, IXGBE_SWSM, swsm);}/** *  ixgbe_calc_eeprom_checksum - Calculates and returns the checksum *  @hw: pointer to hardware structure **/static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw){	u16 i;	u16 j;	u16 checksum = 0;	u16 length = 0;	u16 pointer = 0;	u16 word = 0;	/* Include 0x0-0x3F in the checksum */	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {		if (ixgbe_read_eeprom(hw, i, &word) != 0) {			hw_dbg(hw, "EEPROM read failed\n");			break;		}		checksum += word;	}	/* Include all data from pointers except for the fw pointer */	for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {		ixgbe_read_eeprom(hw, i, &pointer);		/* Make sure the pointer seems valid */		if (pointer != 0xFFFF && pointer != 0) {			ixgbe_read_eeprom(hw, pointer, &length);			if (length != 0xFFFF && length != 0) {				for (j = pointer+1; j <= pointer+length; j++) {					ixgbe_read_eeprom(hw, j, &word);					checksum += word;				}			}		}	}	checksum = (u16)IXGBE_EEPROM_SUM - checksum;	return checksum;}/** *  ixgbe_validate_eeprom_checksum - Validate EEPROM checksum *  @hw: pointer to hardware structure *  @checksum_val: calculated checksum * *  Performs checksum calculation and validates the EEPROM checksum.  If the *  caller does not need checksum_val, the value can be NULL. **/s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val){	s32 status;	u16 checksum;	u16 read_checksum = 0;	/*	 * Read the first word from the EEPROM. If this times out or fails, do	 * not continue or we could be in for a very long wait while every	 * EEPROM read fails	 */	status = ixgbe_read_eeprom(hw, 0, &checksum);	if (status == 0) {		checksum = ixgbe_calc_eeprom_checksum(hw);		ixgbe_read_eeprom(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);		/*		 * Verify read checksum from EEPROM is the same as		 * calculated checksum		 */		if (read_checksum != checksum)			status = IXGBE_ERR_EEPROM_CHECKSUM;		/* If the user cares, return the calculated checksum */		if (checksum_val)			*checksum_val = checksum;	} else {		hw_dbg(hw, "EEPROM read failed\n");	}	return status;}/** *  ixgbe_validate_mac_addr - Validate MAC address *  @mac_addr: pointer to MAC address. * *  Tests a MAC address to ensure it is a valid Individual Address **/s32 ixgbe_validate_mac_addr(u8 *mac_addr){	s32 status = 0;	/* Make sure it is not a multicast address */	if (IXGBE_IS_MULTICAST(mac_addr))		status = IXGBE_ERR_INVALID_MAC_ADDR;	/* Not a broadcast address */	else if (IXGBE_IS_BROADCAST(mac_addr))		status = IXGBE_ERR_INVALID_MAC_ADDR;	/* Reject the zero address */	else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&		 mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)		status = IXGBE_ERR_INVALID_MAC_ADDR;	return status;}/** *  ixgbe_set_rar - Set RX address register *  @hw: pointer to hardware structure *  @addr: Address to put into receive address register *  @index: Receive address register to write *  @vind: Vind to set RAR to *  @enable_addr: set flag that address is active * *  Puts an ethernet address into a receive address register. **/s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,		  u32 enable_addr){	u32 rar_low, rar_high;	/*	 * 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) |		    ((vind << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK));	if (enable_addr != 0)		rar_high |= IXGBE_RAH_AV;	IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);	IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);	return 0;}/** *  ixgbe_init_rx_addrs - Initializes receive address filters. *  @hw: pointer to hardware structure * *  Places the MAC address in receive address register 0 and clears the rest *  of the receive addresss registers. Clears the multicast table. Assumes *  the receiver is in reset when the routine is called. **/static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw){	u32 i;	u32 rar_entries = hw->mac.num_rx_addrs;	/*	 * If the current mac address is valid, assume it is a software override	 * to the permanent address.	 * Otherwise, use the permanent address from the eeprom.	 */	if (ixgbe_validate_mac_addr(hw->mac.addr) ==	    IXGBE_ERR_INVALID_MAC_ADDR) {		/* Get the MAC address from the RAR0 for later reference */		ixgbe_get_mac_addr(hw, hw->mac.addr);		hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ",			  hw->mac.addr[0], hw->mac.addr[1],			  hw->mac.addr[2]);		hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],			  hw->mac.addr[4], hw->mac.addr[5]);	} else {		/* Setup the receive address. */		hw_dbg(hw, "Overriding MAC Address in RAR[0]\n");		hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ",			  hw->mac.addr[0], hw->mac.addr[1],			  hw->mac.addr[2]);		hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],			  hw->mac.addr[4], hw->mac.addr[5]);		ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);	}	hw->addr_ctrl.rar_used_count = 1;	/* Zero out the other receive addresses. */	hw_dbg(hw, "Clearing RAR[1-15]\n");	for (i = 1; i < rar_entries; i++) {		IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);		IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);	}	/* Clear the MTA */	hw->addr_ctrl.mc_addr_in_rar_count = 0;	hw->addr_ctrl.mta_in_use = 0;	IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);	hw_dbg(hw, " Clearing MTA\n");	for (i = 0; i < IXGBE_MC_TBL_SIZE; i++)		IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);	return 0;}/** *  ixgbe_mta_vector - Determines bit-vector in multicast table to set *  @hw: pointer to hardware structure *  @mc_addr: the multicast address * *  Extracts the 12 bits, from a multicast address, to determine which *  bit-vector to set in the multicast table. The hardware uses 12 bits, from *  incoming rx multicast addresses, to determine the bit-vector to check in *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set *  by the MO field of the MCSTCTRL. The MO field is set during initalization *  to mc_filter_type. **/static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr){	u32 vector = 0;	switch (hw->mac.mc_filter_type) {	case 0:	  /* use bits [47:36] of the address */		vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));		break;	case 1:	  /* use bits [46:35] of the address */		vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));		break;	case 2:	  /* use bits [45:34] of the address */		vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));		break;	case 3:	  /* use bits [43:32] of the address */		vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));		break;	default:	 /* Invalid mc_filter_type */		hw_dbg(hw, "MC filter type param set incorrectly\n");		break;	}	/* vector can only be 12-bits or boundary will be exceeded */	vector &= 0xFFF;	return vector;}/** *  ixgbe_set_mta - Set bit-vector in multicast table *  @hw: pointer to hardware structure *  @hash_value: Multicast address hash value * *  Sets the bit-vector in the multicast table. **/static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr){	u32 vector;	u32 vector_bit;	u32 vector_reg;	u32 mta_reg;	hw->addr_ctrl.mta_in_use++;	vector = ixgbe_mta_vector(hw, mc_addr);	hw_dbg(hw, " bit-vector = 0x%03X\n", vector);	/*	 * The MTA is a register array of 128 32-bit registers. It is treated	 * like an array of 4096 bits.  We want to set bit	 * BitArray[vector_value]. So we figure out what register the bit is	 * in, read it, OR in the new bit, then write back the new value.  The	 * register is determined by the upper 7 bits of the vector value and	 * the bit within that register are determined by the lower 5 bits of	 * the value.	 */	vector_reg = (vector >> 5) & 0x7F;	vector_bit = vector & 0x1F;	mta_reg = IXGBE_READ_REG(hw, IXGBE_MTA(vector_reg));	mta_reg |= (1 << vector_bit);	IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);}/**

⌨️ 快捷键说明

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