Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 351452
b: refs/heads/master
c: e428893
h: refs/heads/master
v: v3
  • Loading branch information
Carolyn Wyborny authored and Jeff Kirsher committed Jan 18, 2013
1 parent 438d4f5 commit b925f10
Show file tree
Hide file tree
Showing 9 changed files with 470 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aca5dae8341bc0d340461bdb99749039266a0d81
refs/heads/master: e428893b7d0aecd0ca627c439e7420334824f764
11 changes: 11 additions & 0 deletions trunk/drivers/net/ethernet/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ config IGB
To compile this driver as a module, choose M here. The module
will be called igb.

config IGB_HWMON
bool "Intel(R) PCI-Express Gigabit adapters HWMON support"
default y
depends on IGB && HWMON && !(IGB=y && HWMON=m)
---help---
Say Y if you want to expose thermal sensor data on Intel devices.

Some of our devices contain thermal sensors, both external and internal.
This data is available via the hwmon sysfs interface and exposes
the onboard sensors.

config IGB_DCA
bool "Direct Cache Access (DCA) Support"
default y
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/ethernet/intel/igb/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ obj-$(CONFIG_IGB) += igb.o

igb-objs := igb_main.o igb_ethtool.o e1000_82575.o \
e1000_mac.o e1000_nvm.o e1000_phy.o e1000_mbx.o \
e1000_i210.o igb_ptp.o
e1000_i210.o igb_ptp.o igb_hwmon.o
137 changes: 137 additions & 0 deletions trunk/drivers/net/ethernet/intel/igb/e1000_82575.c
Original file line number Diff line number Diff line change
Expand Up @@ -2303,12 +2303,149 @@ s32 igb_set_eee_i350(struct e1000_hw *hw)
return ret_val;
}

static const u8 e1000_emc_temp_data[4] = {
E1000_EMC_INTERNAL_DATA,
E1000_EMC_DIODE1_DATA,
E1000_EMC_DIODE2_DATA,
E1000_EMC_DIODE3_DATA
};
static const u8 e1000_emc_therm_limit[4] = {
E1000_EMC_INTERNAL_THERM_LIMIT,
E1000_EMC_DIODE1_THERM_LIMIT,
E1000_EMC_DIODE2_THERM_LIMIT,
E1000_EMC_DIODE3_THERM_LIMIT
};

/* igb_get_thermal_sensor_data_generic - Gathers thermal sensor data
* @hw: pointer to hardware structure
*
* Updates the temperatures in mac.thermal_sensor_data
*/
s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw)
{
s32 status = E1000_SUCCESS;
u16 ets_offset;
u16 ets_cfg;
u16 ets_sensor;
u8 num_sensors;
u8 sensor_index;
u8 sensor_location;
u8 i;
struct e1000_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;

if ((hw->mac.type != e1000_i350) || (hw->bus.func != 0))
return E1000_NOT_IMPLEMENTED;

data->sensor[0].temp = (rd32(E1000_THMJT) & 0xFF);

/* Return the internal sensor only if ETS is unsupported */
hw->nvm.ops.read(hw, NVM_ETS_CFG, 1, &ets_offset);
if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF))
return status;

hw->nvm.ops.read(hw, ets_offset, 1, &ets_cfg);
if (((ets_cfg & NVM_ETS_TYPE_MASK) >> NVM_ETS_TYPE_SHIFT)
!= NVM_ETS_TYPE_EMC)
return E1000_NOT_IMPLEMENTED;

num_sensors = (ets_cfg & NVM_ETS_NUM_SENSORS_MASK);
if (num_sensors > E1000_MAX_SENSORS)
num_sensors = E1000_MAX_SENSORS;

for (i = 1; i < num_sensors; i++) {
hw->nvm.ops.read(hw, (ets_offset + i), 1, &ets_sensor);
sensor_index = ((ets_sensor & NVM_ETS_DATA_INDEX_MASK) >>
NVM_ETS_DATA_INDEX_SHIFT);
sensor_location = ((ets_sensor & NVM_ETS_DATA_LOC_MASK) >>
NVM_ETS_DATA_LOC_SHIFT);

if (sensor_location != 0)
hw->phy.ops.read_i2c_byte(hw,
e1000_emc_temp_data[sensor_index],
E1000_I2C_THERMAL_SENSOR_ADDR,
&data->sensor[i].temp);
}
return status;
}

/* igb_init_thermal_sensor_thresh_generic - Sets thermal sensor thresholds
* @hw: pointer to hardware structure
*
* Sets the thermal sensor thresholds according to the NVM map
* and save off the threshold and location values into mac.thermal_sensor_data
*/
s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *hw)
{
s32 status = E1000_SUCCESS;
u16 ets_offset;
u16 ets_cfg;
u16 ets_sensor;
u8 low_thresh_delta;
u8 num_sensors;
u8 sensor_index;
u8 sensor_location;
u8 therm_limit;
u8 i;
struct e1000_thermal_sensor_data *data = &hw->mac.thermal_sensor_data;

if ((hw->mac.type != e1000_i350) || (hw->bus.func != 0))
return E1000_NOT_IMPLEMENTED;

memset(data, 0, sizeof(struct e1000_thermal_sensor_data));

data->sensor[0].location = 0x1;
data->sensor[0].caution_thresh =
(rd32(E1000_THHIGHTC) & 0xFF);
data->sensor[0].max_op_thresh =
(rd32(E1000_THLOWTC) & 0xFF);

/* Return the internal sensor only if ETS is unsupported */
hw->nvm.ops.read(hw, NVM_ETS_CFG, 1, &ets_offset);
if ((ets_offset == 0x0000) || (ets_offset == 0xFFFF))
return status;

hw->nvm.ops.read(hw, ets_offset, 1, &ets_cfg);
if (((ets_cfg & NVM_ETS_TYPE_MASK) >> NVM_ETS_TYPE_SHIFT)
!= NVM_ETS_TYPE_EMC)
return E1000_NOT_IMPLEMENTED;

low_thresh_delta = ((ets_cfg & NVM_ETS_LTHRES_DELTA_MASK) >>
NVM_ETS_LTHRES_DELTA_SHIFT);
num_sensors = (ets_cfg & NVM_ETS_NUM_SENSORS_MASK);

for (i = 1; i <= num_sensors; i++) {
hw->nvm.ops.read(hw, (ets_offset + i), 1, &ets_sensor);
sensor_index = ((ets_sensor & NVM_ETS_DATA_INDEX_MASK) >>
NVM_ETS_DATA_INDEX_SHIFT);
sensor_location = ((ets_sensor & NVM_ETS_DATA_LOC_MASK) >>
NVM_ETS_DATA_LOC_SHIFT);
therm_limit = ets_sensor & NVM_ETS_DATA_HTHRESH_MASK;

hw->phy.ops.write_i2c_byte(hw,
e1000_emc_therm_limit[sensor_index],
E1000_I2C_THERMAL_SENSOR_ADDR,
therm_limit);

if ((i < E1000_MAX_SENSORS) && (sensor_location != 0)) {
data->sensor[i].location = sensor_location;
data->sensor[i].caution_thresh = therm_limit;
data->sensor[i].max_op_thresh = therm_limit -
low_thresh_delta;
}
}
return status;
}

static struct e1000_mac_operations e1000_mac_ops_82575 = {
.init_hw = igb_init_hw_82575,
.check_for_link = igb_check_for_link_82575,
.rar_set = igb_rar_set,
.read_mac_addr = igb_read_mac_addr_82575,
.get_speed_and_duplex = igb_get_speed_and_duplex_copper,
#ifdef CONFIG_IGB_HWMON
.get_thermal_sensor_data = igb_get_thermal_sensor_data_generic,
.init_thermal_sensor_thresh = igb_init_thermal_sensor_thresh_generic,
#endif
};

static struct e1000_phy_operations e1000_phy_ops_82575 = {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/ethernet/intel/igb/e1000_82575.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ void igb_vmdq_set_loopback_pf(struct e1000_hw *, bool);
void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
u16 igb_rxpbs_adjust_82580(u32 data);
s32 igb_set_eee_i350(struct e1000_hw *);
s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *);
s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw);

#define E1000_I2C_THERMAL_SENSOR_ADDR 0xF8
#define E1000_EMC_INTERNAL_DATA 0x00
Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/net/ethernet/intel/igb/e1000_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,10 @@ struct e1000_mac_operations {
s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16);
#ifdef CONFIG_IGB_HWMON
s32 (*get_thermal_sensor_data)(struct e1000_hw *);
s32 (*init_thermal_sensor_thresh)(struct e1000_hw *);
#endif

};

Expand Down
29 changes: 29 additions & 0 deletions trunk/drivers/net/ethernet/intel/igb/igb.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,27 @@ struct igb_i2c_client_list {
struct igb_i2c_client_list *next;
};

#ifdef CONFIG_IGB_HWMON

#define IGB_HWMON_TYPE_LOC 0
#define IGB_HWMON_TYPE_TEMP 1
#define IGB_HWMON_TYPE_CAUTION 2
#define IGB_HWMON_TYPE_MAX 3

struct hwmon_attr {
struct device_attribute dev_attr;
struct e1000_hw *hw;
struct e1000_thermal_diode_data *sensor;
char name[12];
};

struct hwmon_buff {
struct device *device;
struct hwmon_attr *hwmon_list;
unsigned int n_hwmon;
};
#endif

/* board specific private data structure */
struct igb_adapter {
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
Expand Down Expand Up @@ -398,6 +419,10 @@ struct igb_adapter {
struct timecounter tc;

char fw_version[32];
#ifdef CONFIG_IGB_HWMON
struct hwmon_buff igb_hwmon_buff;
bool ets;
#endif
struct i2c_algo_bit_data i2c_algo;
struct i2c_adapter i2c_adap;
struct igb_i2c_client_list *i2c_clients;
Expand Down Expand Up @@ -476,6 +501,10 @@ static inline void igb_ptp_rx_hwtstamp(struct igb_q_vector *q_vector,

extern int igb_ptp_hwtstamp_ioctl(struct net_device *netdev,
struct ifreq *ifr, int cmd);
#ifdef CONFIG_IGB_HWMON
extern void igb_sysfs_exit(struct igb_adapter *adapter);
extern int igb_sysfs_init(struct igb_adapter *adapter);
#endif
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
if (hw->phy.ops.reset)
Expand Down
Loading

0 comments on commit b925f10

Please sign in to comment.