📄 ixgbe_common.c
字号:
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 + -