Newer
Older
set_bit(__NX_DEV_UP, &adapter->state);
/* Usage: During resume and firmware recovery module.*/
static inline int
netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
{
int err = 0;
rtnl_lock();
if (netif_running(netdev))
err = __netxen_nic_up(adapter, netdev);
rtnl_unlock();
return err;
}
/* with rtnl_lock */
__netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
return;
if (!test_and_clear_bit(__NX_DEV_UP, &adapter->state))
return;
spin_lock(&adapter->tx_clean_lock);
if (adapter->stop_port)
adapter->stop_port(adapter);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_p3_free_mac_list(adapter);
adapter->set_promisc(adapter, NETXEN_NIU_NON_PROMISC_MODE);
netxen_napi_disable(adapter);
netxen_release_tx_buffers(adapter);
spin_unlock(&adapter->tx_clean_lock);
/* Usage: During suspend and firmware recovery module */
static inline void
netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
rtnl_lock();
if (netif_running(netdev))
__netxen_nic_down(adapter, netdev);
rtnl_unlock();
}
static int
netxen_nic_attach(struct netxen_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
struct pci_dev *pdev = adapter->pdev;
struct nx_host_rds_ring *rds_ring;
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
return 0;
err = netxen_init_firmware(adapter);
if (err)
return err;
err = netxen_napi_add(adapter, netdev);
if (err)
return err;
err = netxen_alloc_sw_resources(adapter);
if (err) {
printk(KERN_ERR "%s: Error in setting sw resources\n",
netdev->name);
return err;
}
err = netxen_alloc_hw_resources(adapter);
if (err) {
printk(KERN_ERR "%s: Error in setting hw resources\n",
netdev->name);
goto err_out_free_sw;
}
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
tx_ring = adapter->tx_ring;
tx_ring->crb_cmd_producer = netxen_get_ioaddr(adapter,
crb_cmd_producer[adapter->portnum]);
tx_ring->crb_cmd_consumer = netxen_get_ioaddr(adapter,
crb_cmd_consumer[adapter->portnum]);
tx_ring->producer = 0;
tx_ring->sw_consumer = 0;
netxen_nic_update_cmd_producer(adapter, tx_ring);
netxen_nic_update_cmd_consumer(adapter, tx_ring);
for (ring = 0; ring < adapter->max_rds_rings; ring++) {
rds_ring = &adapter->recv_ctx.rds_rings[ring];
netxen_post_rx_buffers(adapter, ring, rds_ring);
}
err = netxen_nic_request_irq(adapter);
if (err) {
dev_err(&pdev->dev, "%s: failed to setup interrupt\n",
netdev->name);
goto err_out_free_rxbuf;
}
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_nic_init_coalesce_defaults(adapter);
netxen_create_sysfs_entries(adapter);
adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
return 0;
err_out_free_rxbuf:
netxen_release_rx_buffers(adapter);
netxen_free_hw_resources(adapter);
err_out_free_sw:
netxen_free_sw_resources(adapter);
return err;
}
static void
netxen_nic_detach(struct netxen_adapter *adapter)
{
if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
return;
netxen_remove_sysfs_entries(adapter);
netxen_free_hw_resources(adapter);
netxen_release_rx_buffers(adapter);
netxen_nic_free_irq(adapter);
netxen_free_sw_resources(adapter);
adapter->is_up = 0;
}
int
netxen_nic_reset_context(struct netxen_adapter *adapter)
{
int err = 0;
struct net_device *netdev = adapter->netdev;
if (test_and_set_bit(__NX_RESETTING, &adapter->state))
return -EBUSY;
if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
if (netif_running(netdev))
__netxen_nic_down(adapter, netdev);
netxen_nic_detach(adapter);
if (netif_running(netdev)) {
err = netxen_nic_attach(adapter);
if (!err)
err = __netxen_nic_up(adapter, netdev);
if (err)
goto done;
}
netif_device_attach(netdev);
clear_bit(__NX_RESETTING, &adapter->state);
static int
netxen_setup_netdev(struct netxen_adapter *adapter,
struct net_device *netdev)
{
int err = 0;
struct pci_dev *pdev = adapter->pdev;
adapter->rx_csum = 1;
adapter->mc_enabled = 0;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
adapter->max_mc_count = 38;
else
adapter->max_mc_count = 16;
netdev->netdev_ops = &netxen_netdev_ops;
netxen_nic_change_mtu(netdev, netdev->mtu);
SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
netdev->features |= (NETIF_F_GRO);
netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
}
if (adapter->pci_using_dac) {
netdev->features |= NETIF_F_HIGHDMA;
netdev->vlan_features |= NETIF_F_HIGHDMA;
}
if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
netdev->features |= (NETIF_F_HW_VLAN_TX);
if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
netdev->features |= NETIF_F_LRO;
netdev->irq = adapter->msix_entries[0].vector;
INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
if (netxen_read_mac_addr(adapter))
dev_warn(&pdev->dev, "failed to read mac addr\n");
netif_carrier_off(netdev);
err = register_netdev(netdev);
if (err) {
dev_err(&pdev->dev, "failed to register net device\n");
return err;
}
return 0;
}
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
#ifdef CONFIG_PCIEAER
static void netxen_mask_aer_correctable(struct netxen_adapter *adapter)
{
struct pci_dev *pdev = adapter->pdev;
struct pci_dev *root = pdev->bus->self;
u32 aer_pos;
if (adapter->ahw.board_type != NETXEN_BRDTYPE_P3_4_GB_MM &&
adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP)
return;
if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT)
return;
aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR);
if (!aer_pos)
return;
pci_write_config_dword(root, aer_pos + PCI_ERR_COR_MASK, 0xffff);
}
#endif
static int __devinit
netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct net_device *netdev = NULL;
struct netxen_adapter *adapter = NULL;
int pci_func_id = PCI_FUNC(pdev->devfn);
if (pdev->revision >= NX_P3_A0 && pdev->revision <= NX_P3_B1) {
pr_warning("%s: chip revisions between 0x%x-0x%x "
module_name(THIS_MODULE), NX_P3_A0, NX_P3_B1);
if ((err = pci_enable_device(pdev)))
return err;
if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
err = -ENODEV;
goto err_out_disable_pdev;
}
if ((err = pci_request_regions(pdev, netxen_nic_driver_name)))
goto err_out_disable_pdev;
if (NX_IS_REVISION_P3(pdev->revision))
pci_enable_pcie_error_reporting(pdev);
netdev = alloc_etherdev(sizeof(struct netxen_adapter));
if(!netdev) {
dev_err(&pdev->dev, "failed to allocate net_device\n");
err = -ENOMEM;
goto err_out_free_res;
}
SET_NETDEV_DEV(netdev, &pdev->dev);
adapter = netdev_priv(netdev);
adapter->netdev = netdev;
adapter->pdev = pdev;
adapter->ahw.pci_func = pci_func_id;
revision_id = pdev->revision;
adapter->ahw.revision_id = revision_id;
rwlock_init(&adapter->ahw.crb_lock);
spin_lock_init(&adapter->ahw.mem_lock);
spin_lock_init(&adapter->tx_clean_lock);
err = netxen_setup_pci_map(adapter);
if (err)
goto err_out_free_netdev;
dhananjay.phadke@gmail.com
committed
/* This will be reset for mezz cards */
adapter->portnum = pci_func_id;
err = netxen_nic_get_board_info(adapter);
if (err) {
dev_err(&pdev->dev, "Error getting board config info.\n");
#ifdef CONFIG_PCIEAER
netxen_mask_aer_correctable(adapter);
#endif
/* Mezz cards have PCI function 0,2,3 enabled */
switch (adapter->ahw.board_type) {
case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
if (pci_func_id >= 2)
adapter->portnum = pci_func_id - 2;
break;
default:
break;
}
if (adapter->portnum == 0) {
val = NXRD32(adapter, NX_CRB_DEV_REF_COUNT);
if (val != 0xffffffff && val != 0) {
NXWR32(adapter, NX_CRB_DEV_REF_COUNT, 0);
adapter->need_fw_reset = 1;
}
}
err = netxen_start_firmware(adapter);
goto err_out_decr_ref;
* See if the firmware gave us a virtual-physical port mapping.
adapter->physical_port = adapter->portnum;
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
i = NXRD32(adapter, CRB_V2P(adapter->portnum));
if (i != 0x55555555)
adapter->physical_port = i;
}
err = netxen_setup_netdev(adapter, netdev);
goto err_out_disable_msi;
pci_set_drvdata(pdev, adapter);
netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
switch (adapter->ahw.port_type) {
case NETXEN_NIC_GBE:
dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
adapter->netdev->name);
break;
case NETXEN_NIC_XGBE:
dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
adapter->netdev->name);
break;
netxen_create_diag_entries(adapter);
return 0;
err_out_disable_msi:
Amit S. Kale
committed
err_out_free_netdev:
free_netdev(netdev);
err_out_free_res:
err_out_disable_pdev:
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
return err;
}
static void __devexit netxen_nic_remove(struct pci_dev *pdev)
{
struct netxen_adapter *adapter;
adapter = pci_get_drvdata(pdev);
if (adapter == NULL)
return;
netdev = adapter->netdev;
netxen_cancel_fw_work(adapter);
Dhananjay Phadke
committed
unregister_netdev(netdev);
cancel_work_sync(&adapter->tx_timeout_task);
netxen_nic_detach(adapter);
Dhananjay Phadke
committed
clear_bit(__NX_RESETTING, &adapter->state);
netxen_remove_diag_entries(adapter);
netxen_release_firmware(adapter);
if (NX_IS_REVISION_P3(pdev->revision))
pci_disable_pcie_error_reporting(pdev);
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
static void netxen_nic_detach_func(struct netxen_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
netif_device_detach(netdev);
netxen_cancel_fw_work(adapter);
if (netif_running(netdev))
netxen_nic_down(adapter, netdev);
cancel_work_sync(&adapter->tx_timeout_task);
netxen_nic_detach(adapter);
if (adapter->portnum == 0)
netxen_free_dummy_dma(adapter);
nx_decr_dev_ref_cnt(adapter);
clear_bit(__NX_RESETTING, &adapter->state);
static int netxen_nic_attach_func(struct pci_dev *pdev)
{
struct netxen_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
int err;
err = pci_enable_device(pdev);
if (err)
return err;
pci_set_power_state(pdev, PCI_D0);
pci_set_master(pdev);
pci_restore_state(pdev);
adapter->ahw.ocm_win = -1;
err = netxen_start_firmware(adapter);
if (err) {
dev_err(&pdev->dev, "failed to start firmware\n");
return err;
}
if (netif_running(netdev)) {
err = netxen_nic_attach(adapter);
if (err)
err = netxen_nic_up(adapter, netdev);
if (err)
netxen_config_indev_addr(netdev, NETDEV_UP);
netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
err_out_detach:
netxen_nic_detach(adapter);
err_out:
nx_decr_dev_ref_cnt(adapter);
return err;
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
static pci_ers_result_t netxen_io_error_detected(struct pci_dev *pdev,
pci_channel_state_t state)
{
struct netxen_adapter *adapter = pci_get_drvdata(pdev);
if (state == pci_channel_io_perm_failure)
return PCI_ERS_RESULT_DISCONNECT;
if (nx_dev_request_aer(adapter))
return PCI_ERS_RESULT_RECOVERED;
netxen_nic_detach_func(adapter);
pci_disable_device(pdev);
return PCI_ERS_RESULT_NEED_RESET;
}
static pci_ers_result_t netxen_io_slot_reset(struct pci_dev *pdev)
{
int err = 0;
err = netxen_nic_attach_func(pdev);
return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
}
static void netxen_io_resume(struct pci_dev *pdev)
{
pci_cleanup_aer_uncorrect_error_status(pdev);
}
static void netxen_nic_shutdown(struct pci_dev *pdev)
{
struct netxen_adapter *adapter = pci_get_drvdata(pdev);
netxen_nic_detach_func(adapter);
if (pci_save_state(pdev))
return;
if (netxen_nic_wol_supported(adapter)) {
pci_enable_wake(pdev, PCI_D3cold, 1);
pci_enable_wake(pdev, PCI_D3hot, 1);
}
pci_disable_device(pdev);
}
#ifdef CONFIG_PM
static int
netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
{
struct netxen_adapter *adapter = pci_get_drvdata(pdev);
int retval;
netxen_nic_detach_func(adapter);
retval = pci_save_state(pdev);
if (retval)
return retval;
if (netxen_nic_wol_supported(adapter)) {
pci_enable_wake(pdev, PCI_D3cold, 1);
pci_enable_wake(pdev, PCI_D3hot, 1);
}
pci_disable_device(pdev);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
return 0;
}
static int
netxen_nic_resume(struct pci_dev *pdev)
{
return netxen_nic_attach_func(pdev);
}
static int netxen_nic_open(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
if (adapter->driver_mismatch)
return -EIO;
err = netxen_nic_attach(adapter);
if (err)
return err;
err = __netxen_nic_up(adapter, netdev);
err_out:
netxen_nic_detach(adapter);
}
/*
* netxen_nic_close - Disables a network interface entry point
*/
static int netxen_nic_close(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
__netxen_nic_down(adapter, netdev);
static void
netxen_tso_check(struct net_device *netdev,
struct nx_host_tx_ring *tx_ring,
struct cmd_desc_type0 *first_desc,
struct sk_buff *skb)
__be16 protocol = skb->protocol;
int copied, offset, copy_len, hdr_len = 0, tso = 0, vlan_oob = 0;
if (protocol == cpu_to_be16(ETH_P_8021Q)) {
vh = (struct vlan_ethhdr *)skb->data;
protocol = vh->h_vlan_encapsulated_proto;
flags = FLAGS_VLAN_TAGGED;
} else if (vlan_tx_tag_present(skb)) {
flags = FLAGS_VLAN_OOB;
vid = vlan_tx_tag_get(skb);
netxen_set_tx_vlan_tci(first_desc, vid);
vlan_oob = 1;
if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
skb_shinfo(skb)->gso_size > 0) {
hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
first_desc->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
first_desc->total_hdr_length = hdr_len;
if (vlan_oob) {
first_desc->total_hdr_length += VLAN_HLEN;
first_desc->tcp_hdr_offset = VLAN_HLEN;
first_desc->ip_hdr_offset = VLAN_HLEN;
/* Only in case of TSO on vlan device */
flags |= FLAGS_VLAN_TAGGED;
}
opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
if (protocol == cpu_to_be16(ETH_P_IP)) {
l4proto = ip_hdr(skb)->protocol;
if (l4proto == IPPROTO_TCP)
opcode = TX_TCP_PKT;
else if(l4proto == IPPROTO_UDP)
opcode = TX_UDP_PKT;
} else if (protocol == cpu_to_be16(ETH_P_IPV6)) {
l4proto = ipv6_hdr(skb)->nexthdr;
if (l4proto == IPPROTO_TCP)
opcode = TX_TCPV6_PKT;
else if(l4proto == IPPROTO_UDP)
opcode = TX_UDPV6_PKT;
}
first_desc->tcp_hdr_offset += skb_transport_offset(skb);
first_desc->ip_hdr_offset += skb_network_offset(skb);
netxen_set_tx_flags_opcode(first_desc, flags, opcode);
if (!tso)
return;
/* For LSO, we need to copy the MAC/IP/TCP headers into
* the descriptor ring
*/
producer = tx_ring->producer;
copied = 0;
offset = 2;
if (vlan_oob) {
/* Create a TSO vlan header template for firmware */
hwdesc = &tx_ring->desc_head[producer];
tx_ring->cmd_buf_arr[producer].skb = NULL;
copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
hdr_len + VLAN_HLEN);
vh = (struct vlan_ethhdr *)((char *)hwdesc + 2);
skb_copy_from_linear_data(skb, vh, 12);
vh->h_vlan_proto = htons(ETH_P_8021Q);
vh->h_vlan_TCI = htons(vid);
skb_copy_from_linear_data_offset(skb, 12,
(char *)vh + 16, copy_len - 16);
offset = 0;
producer = get_next_index(producer, tx_ring->num_desc);
}
while (copied < hdr_len) {
copy_len = min((int)sizeof(struct cmd_desc_type0) - offset,
(hdr_len - copied));
hwdesc = &tx_ring->desc_head[producer];
tx_ring->cmd_buf_arr[producer].skb = NULL;
skb_copy_from_linear_data_offset(skb, copied,
(char *)hwdesc + offset, copy_len);
copied += copy_len;
offset = 0;
producer = get_next_index(producer, tx_ring->num_desc);
}
tx_ring->producer = producer;
barrier();
static int
netxen_map_tx_skb(struct pci_dev *pdev,
struct sk_buff *skb, struct netxen_cmd_buffer *pbuf)
struct netxen_skb_frag *nf;
struct skb_frag_struct *frag;
int i, nr_frags;
dma_addr_t map;
nr_frags = skb_shinfo(skb)->nr_frags;
nf = &pbuf->frag_array[0];
map = pci_map_single(pdev, skb->data,
skb_headlen(skb), PCI_DMA_TODEVICE);
if (pci_dma_mapping_error(pdev, map))
goto out_err;
nf->dma = map;
nf->length = skb_headlen(skb);
for (i = 0; i < nr_frags; i++) {
frag = &skb_shinfo(skb)->frags[i];
nf = &pbuf->frag_array[i+1];
map = pci_map_page(pdev, frag->page, frag->page_offset,
frag->size, PCI_DMA_TODEVICE);
if (pci_dma_mapping_error(pdev, map))
goto unwind;
nf->dma = map;
nf->length = frag->size;
}
return 0;
while (--i >= 0) {
nf = &pbuf->frag_array[i+1];
pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
nf = &pbuf->frag_array[0];
pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
out_err:
return -ENOMEM;
static inline void
netxen_clear_cmddesc(u64 *desc)
{
netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
struct netxen_adapter *adapter = netdev_priv(netdev);
struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
struct netxen_cmd_buffer *pbuf;
struct cmd_desc_type0 *hwdesc, *first_desc;
struct pci_dev *pdev;
frag_count = skb_shinfo(skb)->nr_frags + 1;
if (unlikely(netxen_tx_avail(tx_ring) <= TX_STOP_THRESH)) {
smp_mb();
if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
netif_start_queue(netdev);
else
return NETDEV_TX_BUSY;
pbuf = &tx_ring->cmd_buf_arr[producer];
if (netxen_map_tx_skb(pdev, skb, pbuf))
pbuf->skb = skb;
pbuf->frag_count = frag_count;
first_desc = hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
netxen_set_tx_frags_len(first_desc, frag_count, skb->len);
netxen_set_tx_port(first_desc, adapter->portnum);
for (i = 0; i < frag_count; i++) {
k = i % 4;
if ((k == 0) && (i > 0)) {
/* move to next desc.*/
producer = get_next_index(producer, num_txd);
hwdesc = &tx_ring->desc_head[producer];
netxen_clear_cmddesc((u64 *)hwdesc);
tx_ring->cmd_buf_arr[producer].skb = NULL;
buffrag = &pbuf->frag_array[i];
hwdesc->buffer_length[k] = cpu_to_le16(buffrag->length);
hwdesc->addr_buffer1 = cpu_to_le64(buffrag->dma);
hwdesc->addr_buffer2 = cpu_to_le64(buffrag->dma);
hwdesc->addr_buffer3 = cpu_to_le64(buffrag->dma);
hwdesc->addr_buffer4 = cpu_to_le64(buffrag->dma);
tx_ring->producer = get_next_index(producer, num_txd);
netxen_tso_check(netdev, tx_ring, first_desc, skb);
netxen_nic_update_cmd_producer(adapter, tx_ring);
drop_packet:
adapter->stats.txdropped++;
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
static int netxen_nic_check_temp(struct netxen_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
uint32_t temp, temp_state, temp_val;
int rv = 0;
temp = NXRD32(adapter, CRB_TEMP_STATE);
temp_state = nx_get_temp_state(temp);
temp_val = nx_get_temp_val(temp);
if (temp_state == NX_TEMP_PANIC) {
printk(KERN_ALERT
"%s: Device temperature %d degrees C exceeds"
" maximum allowed. Hardware has been shut down.\n",
rv = 1;
} else if (temp_state == NX_TEMP_WARN) {
if (adapter->temp == NX_TEMP_NORMAL) {
printk(KERN_ALERT
"%s: Device temperature %d degrees C "
"exceeds operating range."
" Immediate action needed.\n",
}
} else {
if (adapter->temp == NX_TEMP_WARN) {
printk(KERN_INFO
"%s: Device temperature is now %d degrees C"
" in normal range.\n", netdev->name,
temp_val);
}
}
adapter->temp = temp_state;
return rv;
}
void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
{
struct net_device *netdev = adapter->netdev;
if (adapter->ahw.linkup && !linkup) {
printk(KERN_INFO "%s: %s NIC Link is down\n",
netxen_nic_driver_name, netdev->name);
adapter->ahw.linkup = 0;
if (netif_running(netdev)) {
netif_carrier_off(netdev);
netif_stop_queue(netdev);
}
adapter->link_changed = !adapter->has_link_events;
} else if (!adapter->ahw.linkup && linkup) {
printk(KERN_INFO "%s: %s NIC Link is up\n",
netxen_nic_driver_name, netdev->name);
adapter->ahw.linkup = 1;
if (netif_running(netdev)) {
netif_carrier_on(netdev);
netif_wake_queue(netdev);
}
adapter->link_changed = !adapter->has_link_events;
static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
{
u32 val, port, linkup;
port = adapter->physical_port;
if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
val = NXRD32(adapter, CRB_XG_STATE_P3);
val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
linkup = (val == XG_LINK_UP_P3);
} else {