Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315404
b: refs/heads/master
c: aed93e0
h: refs/heads/master
v: v3
  • Loading branch information
Michael Chan authored and David S. Miller committed Jul 17, 2012
1 parent 9b0a8d7 commit 101af9e
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cf8d55ae08459d6412779559fb1e88252db86c9d
refs/heads/master: aed93e0bf493535c25c27270001226bb1dd379b2
112 changes: 112 additions & 0 deletions trunk/drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
#include <linux/prefetch.h>
#include <linux/dma-mapping.h>
#include <linux/firmware.h>
#if IS_ENABLED(CONFIG_HWMON)
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#endif

#include <net/checksum.h>
#include <net/ip.h>
Expand Down Expand Up @@ -9481,6 +9485,110 @@ static int tg3_init_hw(struct tg3 *tp, int reset_phy)
return tg3_reset_hw(tp, reset_phy);
}

#if IS_ENABLED(CONFIG_HWMON)
static void tg3_sd_scan_scratchpad(struct tg3 *tp, struct tg3_ocir *ocir)
{
int i;

for (i = 0; i < TG3_SD_NUM_RECS; i++, ocir++) {
u32 off = i * TG3_OCIR_LEN, len = TG3_OCIR_LEN;

tg3_ape_scratchpad_read(tp, (u32 *) ocir, off, len);
off += len;

if (ocir->signature != TG3_OCIR_SIG_MAGIC ||
!(ocir->version_flags & TG3_OCIR_FLAG_ACTIVE))
memset(ocir, 0, TG3_OCIR_LEN);
}
}

/* sysfs attributes for hwmon */
static ssize_t tg3_show_temp(struct device *dev,
struct device_attribute *devattr, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct tg3 *tp = netdev_priv(netdev);
struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
u32 temperature;

spin_lock_bh(&tp->lock);
tg3_ape_scratchpad_read(tp, &temperature, attr->index,
sizeof(temperature));
spin_unlock_bh(&tp->lock);
return sprintf(buf, "%u\n", temperature);
}


static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tg3_show_temp, NULL,
TG3_TEMP_SENSOR_OFFSET);
static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, tg3_show_temp, NULL,
TG3_TEMP_CAUTION_OFFSET);
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, tg3_show_temp, NULL,
TG3_TEMP_MAX_OFFSET);

static struct attribute *tg3_attributes[] = {
&sensor_dev_attr_temp1_input.dev_attr.attr,
&sensor_dev_attr_temp1_crit.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
NULL
};

static const struct attribute_group tg3_group = {
.attrs = tg3_attributes,
};

#endif

static void tg3_hwmon_close(struct tg3 *tp)
{
#if IS_ENABLED(CONFIG_HWMON)
if (tp->hwmon_dev) {
hwmon_device_unregister(tp->hwmon_dev);
tp->hwmon_dev = NULL;
sysfs_remove_group(&tp->pdev->dev.kobj, &tg3_group);
}
#endif
}

static void tg3_hwmon_open(struct tg3 *tp)
{
#if IS_ENABLED(CONFIG_HWMON)
int i, err;
u32 size = 0;
struct pci_dev *pdev = tp->pdev;
struct tg3_ocir ocirs[TG3_SD_NUM_RECS];

tg3_sd_scan_scratchpad(tp, ocirs);

for (i = 0; i < TG3_SD_NUM_RECS; i++) {
if (!ocirs[i].src_data_length)
continue;

size += ocirs[i].src_hdr_length;
size += ocirs[i].src_data_length;
}

if (!size)
return;

/* Register hwmon sysfs hooks */
err = sysfs_create_group(&pdev->dev.kobj, &tg3_group);
if (err) {
dev_err(&pdev->dev, "Cannot create sysfs group, aborting\n");
return;
}

tp->hwmon_dev = hwmon_device_register(&pdev->dev);
if (IS_ERR(tp->hwmon_dev)) {
tp->hwmon_dev = NULL;
dev_err(&pdev->dev, "Cannot register hwmon device, aborting\n");
sysfs_remove_group(&pdev->dev.kobj, &tg3_group);
}
#endif
}


#define TG3_STAT_ADD32(PSTAT, REG) \
do { u32 __val = tr32(REG); \
(PSTAT)->low += __val; \
Expand Down Expand Up @@ -10189,6 +10297,8 @@ static int tg3_open(struct net_device *dev)

tg3_phy_start(tp);

tg3_hwmon_open(tp);

tg3_full_lock(tp, 0);

tg3_timer_start(tp);
Expand Down Expand Up @@ -10238,6 +10348,8 @@ static int tg3_close(struct net_device *dev)

tg3_timer_stop(tp);

tg3_hwmon_close(tp);

tg3_phy_stop(tp);

tg3_full_lock(tp, 1);
Expand Down
38 changes: 38 additions & 0 deletions trunk/drivers/net/ethernet/broadcom/tg3.h
Original file line number Diff line number Diff line change
Expand Up @@ -2676,6 +2676,40 @@ struct tg3_hw_stats {
u8 __reserved4[0xb00-0x9c8];
};

#define TG3_SD_NUM_RECS 3
#define TG3_OCIR_LEN (sizeof(struct tg3_ocir))
#define TG3_OCIR_SIG_MAGIC 0x5253434f
#define TG3_OCIR_FLAG_ACTIVE 0x00000001

#define TG3_TEMP_CAUTION_OFFSET 0xc8
#define TG3_TEMP_MAX_OFFSET 0xcc
#define TG3_TEMP_SENSOR_OFFSET 0xd4


struct tg3_ocir {
u32 signature;
u16 version_flags;
u16 refresh_int;
u32 refresh_tmr;
u32 update_tmr;
u32 dst_base_addr;
u16 src_hdr_offset;
u16 src_hdr_length;
u16 src_data_offset;
u16 src_data_length;
u16 dst_hdr_offset;
u16 dst_data_offset;
u16 dst_reg_upd_offset;
u16 dst_sem_offset;
u32 reserved1[2];
u32 port0_flags;
u32 port1_flags;
u32 port2_flags;
u32 port3_flags;
u32 reserved2[1];
};


/* 'mapping' is superfluous as the chip does not write into
* the tx/rx post rings so we could just fetch it from there.
* But the cache behavior is better how we are doing it now.
Expand Down Expand Up @@ -3211,6 +3245,10 @@ struct tg3 {
const char *fw_needed;
const struct firmware *fw;
u32 fw_len; /* includes BSS */

#if IS_ENABLED(CONFIG_HWMON)
struct device *hwmon_dev;
#endif
};

#endif /* !(_T3_H) */

0 comments on commit 101af9e

Please sign in to comment.