Commit b1cdc467 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (63 commits)
  drivers/net/usb/asix.c: Fix pointer cast.
  be2net: Bug fix to avoid disabling bottom half during firmware upgrade.
  proc_dointvec: write a single value
  hso: add support for new products
  Phonet: fix potential use-after-free in pep_sock_close()
  ath9k: remove VEOL support for ad-hoc
  ath9k: change beacon allocation to prefer the first beacon slot
  sock.h: fix kernel-doc warning
  cls_cgroup: Fix build error when built-in
  macvlan: do proper cleanup in macvlan_common_newlink() V2
  be2net: Bug fix in init code in probe
  net/dccp: expansion of error code size
  ath9k: Fix rx of mcast/bcast frames in PS mode with auto sleep
  wireless: fix sta_info.h kernel-doc warnings
  wireless: fix mac80211.h kernel-doc warnings
  iwlwifi: testing the wrong variable in iwl_add_bssid_station()
  ath9k_htc: rare leak in ath9k_hif_usb_alloc_tx_urbs()
  ath9k_htc: dereferencing before check in hif_usb_tx_cb()
  rt2x00: Fix rt2800usb TX descriptor writing.
  rt2x00: Fix failed SLEEP->AWAKE and AWAKE->SLEEP transitions.
  ...
parents ce7d0226 f925b130
......@@ -1147,6 +1147,12 @@ load_unlock_out:
if (ctr->state == CAPI_CTR_DETECTED)
goto reset_unlock_out;
if (ctr->reset_ctr == NULL) {
printk(KERN_DEBUG "kcapi: reset: no reset function\n");
retval = -ESRCH;
goto reset_unlock_out;
}
ctr->reset_ctr(ctr);
retval = wait_on_ctr_state(ctr, CAPI_CTR_DETECTED);
......
......@@ -921,30 +921,6 @@ void gigaset_isdn_stop(struct cardstate *cs)
* ============================
*/
/*
* load firmware
*/
static int gigaset_load_firmware(struct capi_ctr *ctr, capiloaddata *data)
{
struct cardstate *cs = ctr->driverdata;
/* AVM specific operation, not needed for Gigaset -- ignore */
dev_notice(cs->dev, "load_firmware ignored\n");
return 0;
}
/*
* reset (deactivate) controller
*/
static void gigaset_reset_ctr(struct capi_ctr *ctr)
{
struct cardstate *cs = ctr->driverdata;
/* AVM specific operation, not needed for Gigaset -- ignore */
dev_notice(cs->dev, "reset_ctr ignored\n");
}
/*
* register CAPI application
*/
......@@ -2202,8 +2178,8 @@ int gigaset_isdn_regdev(struct cardstate *cs, const char *isdnid)
iif->ctr.driverdata = cs;
strncpy(iif->ctr.name, isdnid, sizeof(iif->ctr.name));
iif->ctr.driver_name = "gigaset";
iif->ctr.load_firmware = gigaset_load_firmware;
iif->ctr.reset_ctr = gigaset_reset_ctr;
iif->ctr.load_firmware = NULL;
iif->ctr.reset_ctr = NULL;
iif->ctr.register_appl = gigaset_register_appl;
iif->ctr.release_appl = gigaset_release_appl;
iif->ctr.send_message = gigaset_send_message;
......
......@@ -283,6 +283,8 @@ struct be_adapter {
u8 port_type;
u8 transceiver;
u8 generation; /* BladeEngine ASIC generation */
u32 flash_status;
struct completion flash_compl;
bool sriov_enabled;
u32 vf_if_handle[BE_MAX_VF];
......
......@@ -59,6 +59,13 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
CQE_STATUS_COMPL_MASK;
if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) &&
(compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
adapter->flash_status = compl_status;
complete(&adapter->flash_compl);
}
if (compl_status == MCC_STATUS_SUCCESS) {
if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
struct be_cmd_resp_get_stats *resp =
......@@ -1417,6 +1424,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
int status;
spin_lock_bh(&adapter->mcc_lock);
adapter->flash_status = 0;
wrb = wrb_from_mccq(adapter);
if (!wrb) {
......@@ -1428,6 +1436,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
be_wrb_hdr_prepare(wrb, cmd->size, false, 1,
OPCODE_COMMON_WRITE_FLASHROM);
wrb->tag1 = CMD_SUBSYSTEM_COMMON;
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
......@@ -1439,10 +1448,16 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
req->params.op_code = cpu_to_le32(flash_opcode);
req->params.data_buf_size = cpu_to_le32(buf_size);
status = be_mcc_notify_wait(adapter);
be_mcc_notify(adapter);
spin_unlock_bh(&adapter->mcc_lock);
if (!wait_for_completion_timeout(&adapter->flash_compl,
msecs_to_jiffies(12000)))
status = -1;
else
status = adapter->flash_status;
err:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}
......
......@@ -2319,6 +2319,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
spin_lock_init(&adapter->mcc_lock);
spin_lock_init(&adapter->mcc_cq_lock);
init_completion(&adapter->flash_compl);
pci_save_state(adapter->pdev);
return 0;
......@@ -2487,10 +2488,6 @@ static int __devinit be_probe(struct pci_dev *pdev,
status = be_cmd_POST(adapter);
if (status)
goto ctrl_clean;
status = be_cmd_reset_function(adapter);
if (status)
goto ctrl_clean;
}
/* tell fw we're ready to fire cmds */
......@@ -2498,6 +2495,12 @@ static int __devinit be_probe(struct pci_dev *pdev,
if (status)
goto ctrl_clean;
if (be_physfn(adapter)) {
status = be_cmd_reset_function(adapter);
if (status)
goto ctrl_clean;
}
status = be_stats_init(adapter);
if (status)
goto ctrl_clean;
......
......@@ -1626,6 +1626,7 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
return 0;
out_err_mdiobus_register:
kfree(miibus->irq);
mdiobus_free(miibus);
out_err_alloc:
peripheral_free_list(pin_req);
......@@ -1638,6 +1639,7 @@ static int __devexit bfin_mii_bus_remove(struct platform_device *pdev)
struct mii_bus *miibus = platform_get_drvdata(pdev);
platform_set_drvdata(pdev, NULL);
mdiobus_unregister(miibus);
kfree(miibus->irq);
mdiobus_free(miibus);
peripheral_free_list(pin_req);
return 0;
......
......@@ -599,6 +599,8 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
CAN_CTRLMODE_BERR_REPORTING;
spin_lock_init(&priv->cmdreg_lock);
if (sizeof_priv)
priv->priv = (void *)priv + sizeof(struct sja1000_priv);
......
......@@ -1034,9 +1034,10 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac,
{
struct vic_provinfo *vp;
u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
unsigned short *uuid;
u8 *uuid;
char uuid_str[38];
static char *uuid_fmt = "%04X%04X-%04X-%04X-%04X-%04X%04X%04X";
static char *uuid_fmt = "%02X%02X%02X%02X-%02X%02X-%02X%02X-"
"%02X%02X-%02X%02X%02X%02X%0X%02X";
int err;
if (!name)
......@@ -1058,20 +1059,24 @@ static int enic_set_port_profile(struct enic *enic, u8 request, u8 *mac,
ETH_ALEN, mac);
if (instance_uuid) {
uuid = (unsigned short *)instance_uuid;
uuid = instance_uuid;
sprintf(uuid_str, uuid_fmt,
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7]);
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15]);
vic_provinfo_add_tlv(vp,
VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
sizeof(uuid_str), uuid_str);
}
if (host_uuid) {
uuid = (unsigned short *)host_uuid;
uuid = host_uuid;
sprintf(uuid_str, uuid_fmt,
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7]);
uuid[0], uuid[1], uuid[2], uuid[3],
uuid[4], uuid[5], uuid[6], uuid[7],
uuid[8], uuid[9], uuid[10], uuid[11],
uuid[12], uuid[13], uuid[14], uuid[15]);
vic_provinfo_add_tlv(vp,
VIC_LINUX_PROV_TLV_HOST_UUID_STR,
sizeof(uuid_str), uuid_str);
......@@ -1127,6 +1132,14 @@ static int enic_set_vf_port(struct net_device *netdev, int vf,
switch (request) {
case PORT_REQUEST_ASSOCIATE:
/* If the interface mac addr hasn't been assigned,
* assign a random mac addr before setting port-
* profile.
*/
if (is_zero_ether_addr(netdev->dev_addr))
random_ether_addr(netdev->dev_addr);
if (port[IFLA_PORT_PROFILE])
name = nla_data(port[IFLA_PORT_PROFILE]);
......
......@@ -174,6 +174,7 @@ MODULE_PARM_DESC(buffer_size, "DMA buffer allocation size");
* @iobase: pointer to I/O memory region
* @membase: pointer to buffer memory region
* @dma_alloc: dma allocated buffer size
* @io_region_size: I/O memory region size
* @num_tx: number of send buffers
* @cur_tx: last send buffer written
* @dty_tx: last buffer actually sent
......@@ -193,6 +194,7 @@ struct ethoc {
void __iomem *iobase;
void __iomem *membase;
int dma_alloc;
resource_size_t io_region_size;
unsigned int num_tx;
unsigned int cur_tx;
......@@ -943,6 +945,7 @@ static int ethoc_probe(struct platform_device *pdev)
priv = netdev_priv(netdev);
priv->netdev = netdev;
priv->dma_alloc = 0;
priv->io_region_size = mmio->end - mmio->start + 1;
priv->iobase = devm_ioremap_nocache(&pdev->dev, netdev->base_addr,
resource_size(mmio));
......@@ -1047,20 +1050,34 @@ static int ethoc_probe(struct platform_device *pdev)
ret = register_netdev(netdev);
if (ret < 0) {
dev_err(&netdev->dev, "failed to register interface\n");
goto error;
goto error2;
}
goto out;
error2:
netif_napi_del(&priv->napi);
error:
mdiobus_unregister(priv->mdio);
free_mdio:
kfree(priv->mdio->irq);
mdiobus_free(priv->mdio);
free:
if (priv->dma_alloc)
dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
netdev->mem_start);
if (priv) {
if (priv->dma_alloc)
dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
netdev->mem_start);
else if (priv->membase)
devm_iounmap(&pdev->dev, priv->membase);
if (priv->iobase)
devm_iounmap(&pdev->dev, priv->iobase);
}
if (mem)
devm_release_mem_region(&pdev->dev, mem->start,
mem->end - mem->start + 1);
if (mmio)
devm_release_mem_region(&pdev->dev, mmio->start,
mmio->end - mmio->start + 1);
free_netdev(netdev);
out:
return ret;
......@@ -1078,6 +1095,7 @@ static int ethoc_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
if (netdev) {
netif_napi_del(&priv->napi);
phy_disconnect(priv->phy);
priv->phy = NULL;
......@@ -1089,6 +1107,14 @@ static int ethoc_remove(struct platform_device *pdev)
if (priv->dma_alloc)
dma_free_coherent(NULL, priv->dma_alloc, priv->membase,
netdev->mem_start);
else {
devm_iounmap(&pdev->dev, priv->membase);
devm_release_mem_region(&pdev->dev, netdev->mem_start,
netdev->mem_end - netdev->mem_start + 1);
}
devm_iounmap(&pdev->dev, priv->iobase);
devm_release_mem_region(&pdev->dev, netdev->base_addr,
priv->io_region_size);
unregister_netdev(netdev);
free_netdev(netdev);
}
......
......@@ -41,6 +41,7 @@
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/fec.h>
#include <asm/cacheflush.h>
......@@ -182,6 +183,7 @@ struct fec_enet_private {
struct phy_device *phy_dev;
int mii_timeout;
uint phy_speed;
phy_interface_t phy_interface;
int index;
int link;
int full_duplex;
......@@ -1191,6 +1193,21 @@ fec_restart(struct net_device *dev, int duplex)
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
#ifdef FEC_MIIGSK_ENR
if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
/* disable the gasket and wait */
writel(0, fep->hwp + FEC_MIIGSK_ENR);
while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
udelay(1);
/* configure the gasket: RMII, 50 MHz, no loopback, no echo */
writel(1, fep->hwp + FEC_MIIGSK_CFGR);
/* re-enable the gasket */
writel(2, fep->hwp + FEC_MIIGSK_ENR);
}
#endif
/* And last, enable the transmit and receive processing */
writel(2, fep->hwp + FEC_ECNTRL);
writel(0, fep->hwp + FEC_R_DES_ACTIVE);
......@@ -1226,6 +1243,7 @@ static int __devinit
fec_probe(struct platform_device *pdev)
{
struct fec_enet_private *fep;
struct fec_platform_data *pdata;
struct net_device *ndev;
int i, irq, ret = 0;
struct resource *r;
......@@ -1259,6 +1277,10 @@ fec_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, ndev);
pdata = pdev->dev.platform_data;
if (pdata)
fep->phy_interface = pdata->phy;
/* This device has up to three irqs on some platforms */
for (i = 0; i < 3; i++) {
irq = platform_get_irq(pdev, i);
......
......@@ -43,6 +43,8 @@
#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */
#define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */
#else
......
......@@ -107,8 +107,12 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed)
case 57600:
case 115200:
quot = (port->clk + (8 * speed)) / (16 * speed)\
- ANOMALY_05000230;
/*
* IRDA is not affected by anomaly 05000230, so there is no
* need to tweak the divisor like he UART driver (which will
* slightly speed up the baud rate on us).
*/
quot = (port->clk + (8 * speed)) / (16 * speed);
do {
udelay(utime);
......
......@@ -360,6 +360,7 @@ struct ixgbe_adapter {
u32 flags2;
#define IXGBE_FLAG2_RSC_CAPABLE (u32)(1)
#define IXGBE_FLAG2_RSC_ENABLED (u32)(1 << 1)
#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE (u32)(1 << 2)
/* default to trying for four seconds */
#define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
......@@ -407,6 +408,8 @@ struct ixgbe_adapter {
u16 eeprom_version;
int node;
struct work_struct check_overtemp_task;
u32 interrupt_event;
/* SR-IOV */
DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
......
......@@ -1236,6 +1236,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = {
.setup_link = &ixgbe_setup_phy_link_generic,
.setup_link_speed = &ixgbe_setup_phy_link_speed_generic,
.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_82598,
.check_overtemp = &ixgbe_tn_check_overtemp,
};
struct ixgbe_info ixgbe_82598_info = {
......
......@@ -2395,6 +2395,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = {
.write_i2c_byte = &ixgbe_write_i2c_byte_generic,
.read_i2c_eeprom = &ixgbe_read_i2c_eeprom_generic,
.write_i2c_eeprom = &ixgbe_write_i2c_eeprom_generic,
.check_overtemp = &ixgbe_tn_check_overtemp,
};
struct ixgbe_info ixgbe_82599_info = {
......
......@@ -108,6 +108,8 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4),
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM),
board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE),
board_82599 },
......@@ -1618,6 +1620,48 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
}
}
/**
* ixgbe_check_overtemp_task - worker thread to check over tempurature
* @work: pointer to work_struct containing our data
**/
static void ixgbe_check_overtemp_task(struct work_struct *work)
{
struct ixgbe_adapter *adapter = container_of(work,
struct ixgbe_adapter,
check_overtemp_task);
struct ixgbe_hw *hw = &adapter->hw;
u32 eicr = adapter->interrupt_event;
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) {
switch (hw->device_id) {
case IXGBE_DEV_ID_82599_T3_LOM: {
u32 autoneg;
bool link_up = false;
if (hw->mac.ops.check_link)
hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
(eicr & IXGBE_EICR_LSC))
/* Check if this is due to overtemp */
if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
break;
}
return;
default:
if (!(eicr & IXGBE_EICR_GPI_SDP0))
return;
break;
}
DPRINTK(DRV, ERR, "Network adapter has been stopped because it "
"has over heated. Restart the computer. If the problem "
"persists, power off the system and replace the "
"adapter\n");
/* write to clear the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
}
}
static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
{
struct ixgbe_hw *hw = &adapter->hw;
......@@ -1689,6 +1733,10 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
if (hw->mac.type == ixgbe_mac_82599EB) {
ixgbe_check_sfp_event(adapter, eicr);
adapter->interrupt_event = eicr;
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC)))
schedule_work(&adapter->check_overtemp_task);
/* Handle Flow Director Full threshold interrupt */
if (eicr & IXGBE_EICR_FLOW_DIR) {
......@@ -2190,6 +2238,8 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
u32 mask;
mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP0;
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
mask |= IXGBE_EIMS_GPI_SDP1;
if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
......@@ -2250,6 +2300,9 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
ixgbe_check_sfp_event(adapter, eicr);
ixgbe_check_fan_failure(adapter, eicr);
if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC)))
schedule_work(&adapter->check_overtemp_task);
if (napi_schedule_prep(&(q_vector->napi))) {
adapter->tx_ring[0]->total_packets = 0;
......@@ -3265,6 +3318,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
IXGBE_WRITE_REG(hw, IXGBE_EIAM, IXGBE_EICS_RTX_QUEUE);
}
/* Enable Thermal over heat sensor interrupt */
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) {
gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
gpie |= IXGBE_SDP0_GPIEN;
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
}
/* Enable fan failure interrupt if media type is copper */
if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
......@@ -3666,6 +3726,9 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
cancel_work_sync(&adapter->fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
cancel_work_sync(&adapter->check_overtemp_task);
/* disable transmits in the hardware now that interrupts are off */
for (i = 0; i < adapter->num_tx_queues; i++) {
j = adapter->tx_ring[i]->reg_idx;
......@@ -4645,6 +4708,8 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
adapter->flags2 |= IXGBE_FLAG2_RSC_CAPABLE;
adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED;
if (hw->device_id == IXGBE_DEV_ID_82599_T3_LOM)
adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_CAPABLE;
if (dev->features & NETIF_F_NTUPLE) {
/* Flow Director perfect filter enabled */
adapter->flags |= IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
......@@ -6561,7 +6626,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
}
/* reset_hw fills in the perm_addr as well */
hw->phy.reset_if_overtemp = true;
err = hw->mac.ops.reset_hw(hw);
hw->phy.reset_if_overtemp = false;
if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
hw->mac.type == ixgbe_mac_82598EB) {
/*
......@@ -6730,6 +6797,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
INIT_WORK(&adapter->check_overtemp_task, ixgbe_check_overtemp_task);
#ifdef CONFIG_IXGBE_DCA
if (dca_add_requester(&pdev->dev) == 0) {
adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
......
......@@ -135,6 +135,11 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
**/
s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
{
/* Don't reset PHY if it's shut down due to overtemp. */
if (!hw->phy.reset_if_overtemp &&
(IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw)))
return 0;
/*
* Perform soft PHY reset to the PHY_XS.
* This will cause a soft reset to the PHY
......@@ -1345,3 +1350,28 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
return status;
}
/**
* ixgbe_tn_check_overtemp - Checks if an overtemp occured.
* @hw: pointer to hardware structure
*
* Checks if the LASI temp alarm status was triggered due to overtemp
**/
s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw)
{
s32 status = 0;
u16 phy_data = 0;
if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM)
goto out;
/* Check that the LASI temp alarm status was triggered */
hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG,
MDIO_MMD_PMAPMD, &phy_data);
if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM))
goto out;
status = IXGBE_ERR_OVERTEMP;
out:
return status;
}