brintos

brintos / linux-shallow public Read only

0
0
Text · 5.3 KiB · cd1372d Raw
216 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2015 - 2022 Beijing WangXun Technology Co., Ltd. */3 4#include <linux/etherdevice.h>5#include <linux/if_ether.h>6#include <linux/string.h>7#include <linux/iopoll.h>8#include <linux/types.h>9#include <linux/pci.h>10 11#include "../libwx/wx_type.h"12#include "../libwx/wx_hw.h"13#include "txgbe_type.h"14#include "txgbe_hw.h"15 16/**17 *  txgbe_disable_sec_tx_path - Stops the transmit data path18 *  @wx: pointer to hardware structure19 *20 *  Stops the transmit data path and waits for the HW to internally empty21 *  the tx security block22 **/23int txgbe_disable_sec_tx_path(struct wx *wx)24{25	int val;26 27	wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS, WX_TSC_CTL_TX_DIS);28	return read_poll_timeout(rd32, val, val & WX_TSC_ST_SECTX_RDY,29				 1000, 20000, false, wx, WX_TSC_ST);30}31 32/**33 *  txgbe_enable_sec_tx_path - Enables the transmit data path34 *  @wx: pointer to hardware structure35 *36 *  Enables the transmit data path.37 **/38void txgbe_enable_sec_tx_path(struct wx *wx)39{40	wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS, 0);41	WX_WRITE_FLUSH(wx);42}43 44/**45 *  txgbe_init_thermal_sensor_thresh - Inits thermal sensor thresholds46 *  @wx: pointer to hardware structure47 *48 *  Inits the thermal sensor thresholds according to the NVM map49 *  and save off the threshold and location values into mac.thermal_sensor_data50 **/51static void txgbe_init_thermal_sensor_thresh(struct wx *wx)52{53	struct wx_thermal_sensor_data *data = &wx->mac.sensor;54 55	memset(data, 0, sizeof(struct wx_thermal_sensor_data));56 57	/* Only support thermal sensors attached to SP physical port 0 */58	if (wx->bus.func)59		return;60 61	wr32(wx, TXGBE_TS_CTL, TXGBE_TS_CTL_EVAL_MD);62 63	wr32(wx, WX_TS_INT_EN,64	     WX_TS_INT_EN_ALARM_INT_EN | WX_TS_INT_EN_DALARM_INT_EN);65	wr32(wx, WX_TS_EN, WX_TS_EN_ENA);66 67	data->alarm_thresh = 100;68	wr32(wx, WX_TS_ALARM_THRE, 677);69	data->dalarm_thresh = 90;70	wr32(wx, WX_TS_DALARM_THRE, 614);71}72 73/**74 *  txgbe_calc_eeprom_checksum - Calculates and returns the checksum75 *  @wx: pointer to hardware structure76 *  @checksum: pointer to cheksum77 *78 *  Returns a negative error code on error79 **/80static int txgbe_calc_eeprom_checksum(struct wx *wx, u16 *checksum)81{82	u16 *eeprom_ptrs = NULL;83	u16 *local_buffer;84	int status;85	u16 i;86 87	wx_init_eeprom_params(wx);88 89	eeprom_ptrs = kvmalloc_array(TXGBE_EEPROM_LAST_WORD, sizeof(u16),90				     GFP_KERNEL);91	if (!eeprom_ptrs)92		return -ENOMEM;93	/* Read pointer area */94	status = wx_read_ee_hostif_buffer(wx, 0, TXGBE_EEPROM_LAST_WORD, eeprom_ptrs);95	if (status != 0) {96		wx_err(wx, "Failed to read EEPROM image\n");97		kvfree(eeprom_ptrs);98		return status;99	}100	local_buffer = eeprom_ptrs;101 102	for (i = 0; i < TXGBE_EEPROM_LAST_WORD; i++)103		if (i != wx->eeprom.sw_region_offset + TXGBE_EEPROM_CHECKSUM)104			*checksum += local_buffer[i];105 106	kvfree(eeprom_ptrs);107 108	*checksum = TXGBE_EEPROM_SUM - *checksum;109 110	return 0;111}112 113/**114 *  txgbe_validate_eeprom_checksum - Validate EEPROM checksum115 *  @wx: pointer to hardware structure116 *  @checksum_val: calculated checksum117 *118 *  Performs checksum calculation and validates the EEPROM checksum.  If the119 *  caller does not need checksum_val, the value can be NULL.120 **/121int txgbe_validate_eeprom_checksum(struct wx *wx, u16 *checksum_val)122{123	u16 read_checksum = 0;124	u16 checksum;125	int status;126 127	/* Read the first word from the EEPROM. If this times out or fails, do128	 * not continue or we could be in for a very long wait while every129	 * EEPROM read fails130	 */131	status = wx_read_ee_hostif(wx, 0, &checksum);132	if (status) {133		wx_err(wx, "EEPROM read failed\n");134		return status;135	}136 137	checksum = 0;138	status = txgbe_calc_eeprom_checksum(wx, &checksum);139	if (status != 0)140		return status;141 142	status = wx_read_ee_hostif(wx, wx->eeprom.sw_region_offset +143				   TXGBE_EEPROM_CHECKSUM, &read_checksum);144	if (status != 0)145		return status;146 147	/* Verify read checksum from EEPROM is the same as148	 * calculated checksum149	 */150	if (read_checksum != checksum) {151		status = -EIO;152		wx_err(wx, "Invalid EEPROM checksum\n");153	}154 155	/* If the user cares, return the calculated checksum */156	if (checksum_val)157		*checksum_val = checksum;158 159	return status;160}161 162static void txgbe_reset_misc(struct wx *wx)163{164	wx_reset_misc(wx);165	txgbe_init_thermal_sensor_thresh(wx);166}167 168/**169 *  txgbe_reset_hw - Perform hardware reset170 *  @wx: pointer to wx structure171 *172 *  Resets the hardware by resetting the transmit and receive units, masks173 *  and clears all interrupts, perform a PHY reset, and perform a link (MAC)174 *  reset.175 **/176int txgbe_reset_hw(struct wx *wx)177{178	int status;179 180	/* Call adapter stop to disable tx/rx and clear interrupts */181	status = wx_stop_adapter(wx);182	if (status != 0)183		return status;184 185	if (wx->media_type != sp_media_copper) {186		u32 val;187 188		val = WX_MIS_RST_LAN_RST(wx->bus.func);189		wr32(wx, WX_MIS_RST, val | rd32(wx, WX_MIS_RST));190		WX_WRITE_FLUSH(wx);191		usleep_range(10, 100);192	}193 194	status = wx_check_flash_load(wx, TXGBE_SPI_ILDR_STATUS_LAN_SW_RST(wx->bus.func));195	if (status != 0)196		return status;197 198	txgbe_reset_misc(wx);199 200	wx_clear_hw_cntrs(wx);201 202	/* Store the permanent mac address */203	wx_get_mac_addr(wx, wx->mac.perm_addr);204 205	/* Store MAC address from RAR0, clear receive address registers, and206	 * clear the multicast table.  Also reset num_rar_entries to 128,207	 * since we modify this value when programming the SAN MAC address.208	 */209	wx->mac.num_rar_entries = TXGBE_SP_RAR_ENTRIES;210	wx_init_rx_addrs(wx);211 212	pci_set_master(wx->pdev);213 214	return 0;215}216