18199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/***************************************************************************** 28199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 38199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * File: cxgb2.c * 4559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone * $Revision: 1.25 $ * 5559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone * $Date: 2005/06/22 00:43:25 $ * 68199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Description: * 78199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Chelsio 10Gb Ethernet Driver. * 88199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 98199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * This program is free software; you can redistribute it and/or modify * 108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * it under the terms of the GNU General Public License, version 2, as * 118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * published by the Free Software Foundation. * 128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * You should have received a copy of the GNU General Public License along * 148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * with this program; if not, write to the Free Software Foundation, Inc., * 158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * 188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * 198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * 208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * http://www.chelsio.com * 228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * 248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * All rights reserved. * 258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Maintainers: maintainers@chelsio.com * 278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Authors: Dimitrios Michailidis <dm@chelsio.com> * 298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Tina Yang <tainay@chelsio.com> * 308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Felix Marti <felix@chelsio.com> * 318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Scott Bardone <sbardone@chelsio.com> * 328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Kurt Ottaway <kottaway@chelsio.com> * 338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Frank DiMambro <frank@chelsio.com> * 348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * History: * 368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * * 378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ****************************************************************************/ 388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "common.h" 408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/module.h> 418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/init.h> 428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/pci.h> 438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/netdevice.h> 448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/etherdevice.h> 458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/if_vlan.h> 468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/mii.h> 478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <linux/sockios.h> 48559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone#include <linux/dma-mapping.h> 498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include <asm/uaccess.h> 508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "cpl5_cmd.h" 528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "regs.h" 538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "gmac.h" 548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "cphy.h" 558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "sge.h" 56f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#include "tp.h" 578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#include "espi.h" 58f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#include "elmer0.h" 598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 60559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone#include <linux/workqueue.h> 618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 62559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardonestatic inline void schedule_mac_stats_update(struct adapter *ap, int secs) 63559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone{ 64559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone schedule_delayed_work(&ap->stats_update_task, secs * HZ); 65559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone} 668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 67559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardonestatic inline void cancel_mac_stats_update(struct adapter *ap) 68559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone{ 69559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone cancel_delayed_work(&ap->stats_update_task); 70559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone} 718199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 72356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu#define MAX_CMDQ_ENTRIES 16384 73356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu#define MAX_CMDQ1_ENTRIES 1024 74356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu#define MAX_RX_BUFFERS 16384 75356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu#define MAX_RX_JUMBO_BUFFERS 16384 768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define MAX_TX_BUFFERS_HIGH 16384U 778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define MAX_TX_BUFFERS_LOW 1536U 78f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#define MAX_TX_BUFFERS 1460U 79356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu#define MIN_FL_ENTRIES 32 808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ 828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ 838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * The EEPROM is actually bigger but only the first few bytes are used so we 878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * only report those. 888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define EEPROM_SIZE 32 908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 91559fb51ba7e66fe298b8355fabde1275b7def35fScott BardoneMODULE_DESCRIPTION(DRV_DESCRIPTION); 928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph LameterMODULE_AUTHOR("Chelsio Communications"); 938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph LameterMODULE_LICENSE("GPL"); 948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int dflt_msg_enable = DFLT_MSG_ENABLE; 968199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 978d3b33f67fdc0fb364a1ef6d8fbbea7c2e4e6c98Rusty Russellmodule_param(dflt_msg_enable, int, 0); 98f1d3d38af75789f1b82969b83b69cab540609789Stephen HemmingerMODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 default message enable bitmap"); 99f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 100f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#define HCLOCK 0x0 101f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger#define LCLOCK 0x1 102f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 103f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger/* T1 cards powersave mode */ 104f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic int t1_clock(struct adapter *adapter, int mode); 105f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic int t1powersave = 1; /* HW default is powersave mode. */ 1068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 107f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingermodule_param(t1powersave, int, 0); 108f1d3d38af75789f1b82969b83b69cab540609789Stephen HemmingerMODULE_PARM_DESC(t1powersave, "Enable/Disable T1 powersaving mode"); 1098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 110325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemmingerstatic int disable_msi = 0; 111325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemmingermodule_param(disable_msi, int, 0); 112325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen HemmingerMODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); 1138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic const char pci_speed[][4] = { 1158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter "33", "66", "100", "133" 1168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter}; 1178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 1198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Setup MAC to receive the types of packets we want. 1208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 1218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void t1_set_rxmode(struct net_device *dev) 1228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 123c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 1248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct cmac *mac = adapter->port[dev->if_port].mac; 1258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct t1_rx_mode rm; 1268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter rm.dev = dev; 1288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mac->ops->set_rx_mode(mac, &rm); 1298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void link_report(struct port_info *p) 1328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 1338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!netif_carrier_ok(p->dev)) 134205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger printk(KERN_INFO "%s: link down\n", p->dev->name); 1358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else { 136559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone const char *s = "10Mbps"; 1378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter switch (p->link_config.speed) { 139559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone case SPEED_10000: s = "10Gbps"; break; 140559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone case SPEED_1000: s = "1000Mbps"; break; 141559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone case SPEED_100: s = "100Mbps"; break; 1428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 1438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 144356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu printk(KERN_INFO "%s: link up, %s, %s-duplex\n", 1458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter p->dev->name, s, 1468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); 1478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 1488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 150f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingervoid t1_link_negotiated(struct adapter *adapter, int port_id, int link_stat, 1518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int speed, int duplex, int pause) 1528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 1538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[port_id]; 1548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (link_stat != netif_carrier_ok(p->dev)) { 1568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (link_stat) 1578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netif_carrier_on(p->dev); 1588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else 1598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netif_carrier_off(p->dev); 1608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter link_report(p); 1618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 162f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* multi-ports: inform toe */ 163f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if ((speed > 0) && (adapter->params.nports > 1)) { 164f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger unsigned int sched_speed = 10; 165f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger switch (speed) { 166f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger case SPEED_1000: 167f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger sched_speed = 1000; 168f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger break; 169f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger case SPEED_100: 170f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger sched_speed = 100; 171f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger break; 172f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger case SPEED_10: 173f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger sched_speed = 10; 174f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger break; 175f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 176f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger t1_sched_update_parms(adapter->sge, port_id, 0, sched_speed); 177f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 1788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 1798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void link_start(struct port_info *p) 1828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 1838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct cmac *mac = p->mac; 1848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mac->ops->reset(mac); 1868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (mac->ops->macaddress_set) 1878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mac->ops->macaddress_set(mac, p->dev->dev_addr); 1888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_set_rxmode(p->dev); 1898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_link_start(p->phy, mac, &p->link_config); 1908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); 1918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void enable_hw_csum(struct adapter *adapter) 1948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 19530f554f925335abad89aaa38eec6828242b27527Michał Mirosław if (adapter->port[0].dev->hw_features & NETIF_F_TSO) 196f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */ 197f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger t1_tp_set_tcp_checksum_offload(adapter->tp, 1); 1988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 1998199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 2018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Things to do upon first use of a card. 2028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * This must run with the rtnl lock held. 2038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 2048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int cxgb_up(struct adapter *adapter) 2058199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 2068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int err = 0; 2078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2088199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!(adapter->flags & FULL_INIT_DONE)) { 2098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = t1_init_hw_modules(adapter); 2108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (err) 2118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_err; 2128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter enable_hw_csum(adapter); 2148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->flags |= FULL_INIT_DONE; 2158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 2168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_interrupts_clear(adapter); 218325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger 2197fe26a60e08f38c797851fb3b444d753af616112Stephen Hemminger adapter->params.has_msi = !disable_msi && !pci_enable_msi(adapter->pdev); 2207fe26a60e08f38c797851fb3b444d753af616112Stephen Hemminger err = request_irq(adapter->pdev->irq, t1_interrupt, 221325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger adapter->params.has_msi ? 0 : IRQF_SHARED, 222325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger adapter->name, adapter); 223325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger if (err) { 224325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger if (adapter->params.has_msi) 225325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger pci_disable_msi(adapter->pdev); 226325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger 2278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_err; 228559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone } 229325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger 2308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_sge_start(adapter->sge); 2318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_interrupts_enable(adapter); 232356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieuout_err: 2338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return err; 2348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 2378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Release resources when all the ports have been stopped. 2388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 2398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void cxgb_down(struct adapter *adapter) 2408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 2418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_sge_stop(adapter->sge); 2428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_interrupts_disable(adapter); 2438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter free_irq(adapter->pdev->irq, adapter); 244325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger if (adapter->params.has_msi) 245325dde48914e8ec1614d79ffacdbf9c0b8d24f42Stephen Hemminger pci_disable_msi(adapter->pdev); 2468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int cxgb_open(struct net_device *dev) 2498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 2508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int err; 251c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 2528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int other_ports = adapter->open_device_map & PORT_MASK; 2538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 254bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger napi_enable(&adapter->napi); 255bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) { 256bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger napi_disable(&adapter->napi); 2578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return err; 258bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger } 2598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter __set_bit(dev->if_port, &adapter->open_device_map); 2618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter link_start(&adapter->port[dev->if_port]); 2628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netif_start_queue(dev); 2638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!other_ports && adapter->params.stats_update_period) 2648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter schedule_mac_stats_update(adapter, 2658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.stats_update_period); 266133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko 267133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko t1_vlan_mode(adapter, dev->features); 2688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 2698199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2718199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int cxgb_close(struct net_device *dev) 2728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 273c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 2748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[dev->if_port]; 2758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct cmac *mac = p->mac; 2768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netif_stop_queue(dev); 278bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger napi_disable(&adapter->napi); 2798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); 2808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netif_carrier_off(dev); 2818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter clear_bit(dev->if_port, &adapter->open_device_map); 2838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (adapter->params.stats_update_period && 2848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter !(adapter->open_device_map & PORT_MASK)) { 2858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* Stop statistics accumulation. */ 2868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter smp_mb__after_clear_bit(); 2878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock(&adapter->work_lock); /* sync with update task */ 2888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_unlock(&adapter->work_lock); 2898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cancel_mac_stats_update(adapter); 2908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 2918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!adapter->open_device_map) 2938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cxgb_down(adapter); 2948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 2958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 2968199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 2978199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic struct net_device_stats *t1_get_stats(struct net_device *dev) 2988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 299c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 3008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[dev->if_port]; 3018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct net_device_stats *ns = &p->netstats; 3028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter const struct cmac_statistics *pstats; 3038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* Do a full update of the MAC stats */ 3058199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats = p->mac->ops->statistics_update(p->mac, 306205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger MAC_STATS_UPDATE_FULL); 3078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3088199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_packets = pstats->TxUnicastFramesOK + 3098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK; 3108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_packets = pstats->RxUnicastFramesOK + 3128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK; 3138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_bytes = pstats->TxOctetsOK; 3158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_bytes = pstats->RxOctetsOK; 3168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors + 3188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions; 3198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors + 3208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->RxFCSErrors + pstats->RxAlignErrors + 3218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors + 3228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->RxSymbolErrors + pstats->RxRuntErrors; 3238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->multicast = pstats->RxMulticastFramesOK; 3258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->collisions = pstats->TxTotalCollisions; 3268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* detailed rx_errors */ 3288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_length_errors = pstats->RxFrameTooLongErrors + 3298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pstats->RxJabberErrors; 3308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_over_errors = 0; 3318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_crc_errors = pstats->RxFCSErrors; 3328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_frame_errors = pstats->RxAlignErrors; 3338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_fifo_errors = 0; 3348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->rx_missed_errors = 0; 3358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* detailed tx_errors */ 3378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions; 3388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_carrier_errors = 0; 3398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_fifo_errors = pstats->TxUnderrun; 3408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_heartbeat_errors = 0; 3418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ns->tx_window_errors = pstats->TxLateCollisions; 3428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return ns; 3438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 3448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic u32 get_msglevel(struct net_device *dev) 3468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 347c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 3488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return adapter->msg_enable; 3508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 3518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void set_msglevel(struct net_device *dev, u32 val) 3538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 354c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 3558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->msg_enable = val; 3578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 3588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 3598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic char stats_strings[][ETH_GSTRING_LEN] = { 360205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxOctetsOK", 361205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxOctetsBad", 362205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxUnicastFramesOK", 363205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxMulticastFramesOK", 364205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxBroadcastFramesOK", 365205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxPauseFrames", 366205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxFramesWithDeferredXmissions", 367205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxLateCollisions", 368205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxTotalCollisions", 369205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxFramesAbortedDueToXSCollisions", 370205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxUnderrun", 371205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxLengthErrors", 372205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxInternalMACXmitError", 373205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxFramesWithExcessiveDeferral", 374205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "TxFCSErrors", 375e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray "TxJumboFramesOk", 376e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray "TxJumboOctetsOk", 377e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray 378205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxOctetsOK", 379205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxOctetsBad", 380205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxUnicastFramesOK", 381205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxMulticastFramesOK", 382205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxBroadcastFramesOK", 383205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxPauseFrames", 384205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxFCSErrors", 385205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxAlignErrors", 386205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxSymbolErrors", 387205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxDataErrors", 388205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxSequenceErrors", 389205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxRuntErrors", 390205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxJabberErrors", 391205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxInternalMACRcvError", 392205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxInRangeLengthErrors", 393205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxOutOfRangeLengthField", 394205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger "RxFrameTooLongErrors", 395e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray "RxJumboFramesOk", 396e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray "RxJumboOctetsOk", 397559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 39856f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger /* Port stats */ 399559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "RxCsumGood", 400559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "TxCsumOffload", 40156f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger "TxTso", 40256f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger "RxVlan", 40356f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger "TxVlan", 4047832ee034b6ef78aab020c9ec1348544cd65ccbdDivy Le Ray "TxNeedHeadroom", 4057832ee034b6ef78aab020c9ec1348544cd65ccbdDivy Le Ray 40656f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger /* Interrupt stats */ 40756f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger "rx drops", 40856f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger "pure_rsps", 40956f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger "unhandled irqs", 410559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "respQ_empty", 411559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "respQ_overflow", 412559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "freelistQ_empty", 413559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "pkt_too_big", 414559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "pkt_mismatch", 415559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "cmdQ_full0", 416559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "cmdQ_full1", 417205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger 418559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "espi_DIP2ParityErr", 419559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "espi_DIP4Err", 420559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "espi_RxDrops", 421559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "espi_TxDrops", 422559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "espi_RxOvfl", 423559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone "espi_ParityErr" 4248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter}; 425205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger 426559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone#define T2_REGMAP_SIZE (3 * 1024) 427559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 428559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardonestatic int get_regs_len(struct net_device *dev) 429559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone{ 430559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone return T2_REGMAP_SIZE; 431559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone} 4328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 4338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 4348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 435c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 4368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 43723020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); 43823020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones strlcpy(info->version, DRV_VERSION, sizeof(info->version)); 43923020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones strlcpy(info->bus_info, pci_name(adapter->pdev), 44023020ab35364f2c91133b099c2b1f7458e29aa96Rick Jones sizeof(info->bus_info)); 4418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 4428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 443b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzikstatic int get_sset_count(struct net_device *dev, int sset) 4448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 445b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik switch (sset) { 446b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik case ETH_SS_STATS: 447b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik return ARRAY_SIZE(stats_strings); 448b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik default: 449b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik return -EOPNOTSUPP; 450b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik } 4518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 4528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 4538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void get_strings(struct net_device *dev, u32 stringset, u8 *data) 4548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 4558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (stringset == ETH_SS_STATS) 4568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter memcpy(data, stats_strings, sizeof(stats_strings)); 4578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 4588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 4598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void get_stats(struct net_device *dev, struct ethtool_stats *stats, 4608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter u64 *data) 4618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 462c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 4638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct cmac *mac = adapter->port[dev->if_port].mac; 4648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter const struct cmac_statistics *s; 465559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone const struct sge_intr_counts *t; 46656f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger struct sge_port_stats ss; 4678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 4688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); 469e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray t = t1_sge_get_intr_counts(adapter->sge); 47056f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss); 47156f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger 472e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxOctetsOK; 473e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxOctetsBad; 474e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxUnicastFramesOK; 475e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxMulticastFramesOK; 476e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxBroadcastFramesOK; 477e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxPauseFrames; 478e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxFramesWithDeferredXmissions; 479e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxLateCollisions; 480e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxTotalCollisions; 481e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxFramesAbortedDueToXSCollisions; 482e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxUnderrun; 483e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxLengthErrors; 484e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxInternalMACXmitError; 485e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxFramesWithExcessiveDeferral; 486e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxFCSErrors; 487e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxJumboFramesOK; 488e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->TxJumboOctetsOK; 489e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray 490e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxOctetsOK; 491e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxOctetsBad; 492e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxUnicastFramesOK; 493e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxMulticastFramesOK; 494e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxBroadcastFramesOK; 495e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxPauseFrames; 496e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxFCSErrors; 497e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxAlignErrors; 498e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxSymbolErrors; 499e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxDataErrors; 500e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxSequenceErrors; 501e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxRuntErrors; 502e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxJabberErrors; 503e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxInternalMACRcvError; 504e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxInRangeLengthErrors; 505e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxOutOfRangeLengthField; 506e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxFrameTooLongErrors; 507e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxJumboFramesOK; 508e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = s->RxJumboOctetsOK; 509e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray 510e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = ss.rx_cso_good; 511e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = ss.tx_cso; 512e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = ss.tx_tso; 513e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = ss.vlan_xtract; 514e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = ss.vlan_insert; 515e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray *data++ = ss.tx_need_hdrroom; 516e0348b9ae5374f9a24424ae680bcd80724415f60Divy Le Ray 51756f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->rx_drops; 51856f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->pure_rsps; 51956f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->unhandled_irqs; 52056f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->respQ_empty; 52156f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->respQ_overflow; 52256f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->freelistQ_empty; 52356f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->pkt_too_big; 52456f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->pkt_mismatch; 52556f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->cmdQ_full[0]; 52656f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = t->cmdQ_full[1]; 527f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 528f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (adapter->espi) { 529f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger const struct espi_intr_counts *e; 530f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 531f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger e = t1_espi_get_intr_counts(adapter->espi); 53256f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = e->DIP2_parity_err; 53356f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = e->DIP4_err; 53456f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = e->rx_drops; 53556f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = e->tx_drops; 53656f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = e->rx_ovflw; 53756f643c28c5df63693d7c66e56f8e4767cfd7a65Stephen Hemminger *data++ = e->parity_err; 538f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 539559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone} 540559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 541559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardonestatic inline void reg_block_dump(struct adapter *ap, void *buf, 542559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone unsigned int start, unsigned int end) 543559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone{ 544559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone u32 *p = buf + start; 545559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 546559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone for ( ; start <= end; start += sizeof(u32)) 547559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone *p++ = readl(ap->regs + start); 548559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone} 5498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 550559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardonestatic void get_regs(struct net_device *dev, struct ethtool_regs *regs, 551559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone void *buf) 552559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone{ 553c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *ap = dev->ml_priv; 554559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 555559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone /* 556559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone * Version scheme: bits 0..9: chip version, bits 10..15: chip revision 557559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone */ 558559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone regs->version = 2; 559559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 560559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone memset(buf, 0, T2_REGMAP_SIZE); 561559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER); 562f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE); 563f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR); 564f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT); 565f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE); 566f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE); 567f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT); 568f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL); 569f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE); 570f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD); 5718199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 5728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 5738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 5748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 575c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 5768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[dev->if_port]; 5778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 5788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->supported = p->link_config.supported; 5798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->advertising = p->link_config.advertising; 5808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 5818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (netif_carrier_ok(dev)) { 582707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny ethtool_cmd_speed_set(cmd, p->link_config.speed); 5838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->duplex = p->link_config.duplex; 5848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } else { 585707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny ethtool_cmd_speed_set(cmd, -1); 5868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->duplex = -1; 5878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 5888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 589205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; 59023c3320cb039debfb94b27e8e9bfe26dd47692c3Ben Hutchings cmd->phy_address = p->phy->mdio.prtad; 591205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger cmd->transceiver = XCVR_EXTERNAL; 592205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger cmd->autoneg = p->link_config.autoneg; 593205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger cmd->maxtxpkt = 0; 594205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger cmd->maxrxpkt = 0; 5958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 5968199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 5978199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 5988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int speed_duplex_to_caps(int speed, int duplex) 5998199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 6008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int cap = 0; 6018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter switch (speed) { 6038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter case SPEED_10: 6048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (duplex == DUPLEX_FULL) 6058199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_10baseT_Full; 6068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else 6078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_10baseT_Half; 6088199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter break; 6098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter case SPEED_100: 6108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (duplex == DUPLEX_FULL) 6118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_100baseT_Full; 6128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else 6138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_100baseT_Half; 6148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter break; 6158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter case SPEED_1000: 6168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (duplex == DUPLEX_FULL) 6178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_1000baseT_Full; 6188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else 6198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_1000baseT_Half; 6208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter break; 6218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter case SPEED_10000: 6228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (duplex == DUPLEX_FULL) 6238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cap = SUPPORTED_10000baseT_Full; 6248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 6258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return cap; 6268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 6278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \ 6298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \ 6308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \ 6318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ADVERTISED_10000baseT_Full) 6328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 6348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 635c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 6368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[dev->if_port]; 6378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct link_config *lc = &p->link_config; 6388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!(lc->supported & SUPPORTED_Autoneg)) 640559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone return -EOPNOTSUPP; /* can't change speed/duplex */ 6418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (cmd->autoneg == AUTONEG_DISABLE) { 64325db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny u32 speed = ethtool_cmd_speed(cmd); 64425db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny int cap = speed_duplex_to_caps(speed, cmd->duplex); 6458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 64625db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny if (!(lc->supported & cap) || (speed == SPEED_1000)) 6478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return -EINVAL; 64825db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny lc->requested_speed = speed; 6498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_duplex = cmd->duplex; 6508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->advertising = 0; 6518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } else { 6528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->advertising &= ADVERTISED_MASK; 6538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (cmd->advertising & (cmd->advertising - 1)) 6548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->advertising = lc->supported; 6558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter cmd->advertising &= lc->supported; 6568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!cmd->advertising) 6578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return -EINVAL; 6588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_speed = SPEED_INVALID; 6598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_duplex = DUPLEX_INVALID; 6608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->advertising = cmd->advertising | ADVERTISED_Autoneg; 6618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 6628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->autoneg = cmd->autoneg; 6638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (netif_running(dev)) 6648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_link_start(p->phy, p->mac, lc); 6658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 6668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 6678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void get_pauseparam(struct net_device *dev, 6698199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct ethtool_pauseparam *epause) 6708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 671c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 6728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[dev->if_port]; 6738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0; 6758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0; 6768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0; 6778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 6788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int set_pauseparam(struct net_device *dev, 6808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct ethtool_pauseparam *epause) 6818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 682c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 6838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[dev->if_port]; 6848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct link_config *lc = &p->link_config; 6858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (epause->autoneg == AUTONEG_DISABLE) 6878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_fc = 0; 6888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else if (lc->supported & SUPPORTED_Autoneg) 6898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_fc = PAUSE_AUTONEG; 6908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else 6918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return -EINVAL; 6928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 6938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (epause->rx_pause) 6948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_fc |= PAUSE_RX; 6958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (epause->tx_pause) 6968199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->requested_fc |= PAUSE_TX; 6978199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (lc->autoneg == AUTONEG_ENABLE) { 6988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (netif_running(dev)) 6998199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_link_start(p->phy, p->mac, lc); 7008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } else { 7018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); 7028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (netif_running(dev)) 7038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1, 7048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter lc->fc); 7058199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 7068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 7078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7088199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) 7108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 711c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 7128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; 7138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_max_pending = MAX_RX_BUFFERS; 7158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS; 7168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->tx_max_pending = MAX_CMDQ_ENTRIES; 7178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl]; 7198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl]; 7208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->tx_pending = adapter->params.sge.cmdQ_size[0]; 7218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) 7248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 725c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 7268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0; 7278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending || 7298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS || 7308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->tx_pending > MAX_CMDQ_ENTRIES || 7318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_pending < MIN_FL_ENTRIES || 7328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->rx_jumbo_pending < MIN_FL_ENTRIES || 7338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1)) 7348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return -EINVAL; 7358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (adapter->flags & FULL_INIT_DONE) 737356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return -EBUSY; 7388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; 7408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; 7418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.sge.cmdQ_size[0] = e->tx_pending; 7428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ? 7438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter MAX_CMDQ1_ENTRIES : e->tx_pending; 7448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 7458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c) 7488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 749c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 7508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7517fe26a60e08f38c797851fb3b444d753af616112Stephen Hemminger adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; 752356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce; 7538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.sge.sample_interval_usecs = c->rate_sample_interval; 7548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge); 7558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 7568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) 7598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 760c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 7618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 762559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs; 7638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter c->rate_sample_interval = adapter->params.sge.sample_interval_usecs; 7648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable; 7658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 7668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int get_eeprom_len(struct net_device *dev) 7698199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 770c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 771f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 772356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return t1_is_asic(adapter) ? EEPROM_SIZE : 0; 7738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#define EEPROM_MAGIC(ap) \ 7768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16)) 7778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e, 7798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter u8 *data) 7808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 7818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int i; 7828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter u8 buf[EEPROM_SIZE] __attribute__((aligned(4))); 783c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 7848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter e->magic = EEPROM_MAGIC(adapter); 7868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32)) 787ac390c60a833192e87fb09ed8d67f5d1a84306c8Al Viro t1_seeprom_read(adapter, i, (__le32 *)&buf[i]); 7888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter memcpy(data, buf + e->offset, e->len); 7898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 7908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 7918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 7927282d491ecaee9883233a0e27283c4c79486279aJeff Garzikstatic const struct ethtool_ops t1_ethtool_ops = { 7938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_settings = get_settings, 7948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .set_settings = set_settings, 7958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_drvinfo = get_drvinfo, 7968199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_msglevel = get_msglevel, 7978199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .set_msglevel = set_msglevel, 7988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_ringparam = get_sge_param, 7998199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .set_ringparam = set_sge_param, 8008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_coalesce = get_coalesce, 8018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .set_coalesce = set_coalesce, 8028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_eeprom_len = get_eeprom_len, 8038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_eeprom = get_eeprom, 8048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_pauseparam = get_pauseparam, 8058199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .set_pauseparam = set_pauseparam, 8068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_link = ethtool_op_get_link, 8078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_strings = get_strings, 808b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik .get_sset_count = get_sset_count, 8098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .get_ethtool_stats = get_stats, 810559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone .get_regs_len = get_regs_len, 811559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone .get_regs = get_regs, 8128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter}; 8138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) 8158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 816c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 81723c3320cb039debfb94b27e8e9bfe26dd47692c3Ben Hutchings struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio; 8188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 81923c3320cb039debfb94b27e8e9bfe26dd47692c3Ben Hutchings return mdio_mii_ioctl(mdio, if_mii(req), cmd); 8208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 8218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int t1_change_mtu(struct net_device *dev, int new_mtu) 8238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 8248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int ret; 825c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 8268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct cmac *mac = adapter->port[dev->if_port].mac; 8278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8288199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!mac->ops->set_mtu) 829356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return -EOPNOTSUPP; 8308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (new_mtu < 68) 831356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu return -EINVAL; 8328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if ((ret = mac->ops->set_mtu(mac, new_mtu))) 8338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return ret; 8348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter dev->mtu = new_mtu; 8358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 8368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 8378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int t1_set_mac_addr(struct net_device *dev, void *p) 8398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 840c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 8418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct cmac *mac = adapter->port[dev->if_port].mac; 8428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct sockaddr *addr = p; 8438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!mac->ops->macaddress_set) 8458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return -EOPNOTSUPP; 8468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 8488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mac->ops->macaddress_set(mac, dev->dev_addr); 8498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 8508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 8518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 852c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosławstatic netdev_features_t t1_fix_features(struct net_device *dev, 853c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław netdev_features_t features) 8548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 855133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko /* 856133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko * Since there is no support for separate rx/tx vlan accel 857133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko * enable/disable make sure tx flag is always in same state as rx. 858133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko */ 859133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko if (features & NETIF_F_HW_VLAN_RX) 860133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko features |= NETIF_F_HW_VLAN_TX; 861133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko else 862133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko features &= ~NETIF_F_HW_VLAN_TX; 8638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 864133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko return features; 8658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 8668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 867c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosławstatic int t1_set_features(struct net_device *dev, netdev_features_t features) 868133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko{ 869c8f44affb7244f2ac3e703cab13d55ede27621bbMichał Mirosław netdev_features_t changed = dev->features ^ features; 870133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko struct adapter *adapter = dev->ml_priv; 871133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko 872133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko if (changed & NETIF_F_HW_VLAN_RX) 873133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko t1_vlan_mode(adapter, features); 874133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko 875133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko return 0; 876133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko} 8778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#ifdef CONFIG_NET_POLL_CONTROLLER 8788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void t1_netpoll(struct net_device *dev) 8798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 880559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone unsigned long flags; 881c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 8828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 883559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone local_irq_save(flags); 8847fe26a60e08f38c797851fb3b444d753af616112Stephen Hemminger t1_interrupt(adapter->pdev->irq, adapter); 885559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone local_irq_restore(flags); 8868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 8878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter#endif 8888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8898199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 8908199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Periodic accumulation of MAC statistics. This is used only if the MAC 8918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * does not have any other way to prevent stats counter overflow. 8928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 893c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howellsstatic void mac_stats_task(struct work_struct *work) 8948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 8958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int i; 896c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct adapter *adapter = 897c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells container_of(work, struct adapter, stats_update_task.work); 8988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 8998199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter for_each_port(adapter, i) { 9008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *p = &adapter->port[i]; 9018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (netif_running(p->dev)) 9038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter p->mac->ops->statistics_update(p->mac, 9048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter MAC_STATS_UPDATE_FAST); 9058199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 9068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9078199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* Schedule the next statistics update if any port is active. */ 9088199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock(&adapter->work_lock); 9098199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (adapter->open_device_map & PORT_MASK) 9108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter schedule_mac_stats_update(adapter, 9118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.stats_update_period); 9128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_unlock(&adapter->work_lock); 9138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 9148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 9168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Processes elmer0 external interrupts in process context. 9178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 918c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howellsstatic void ext_intr_task(struct work_struct *work) 9198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 920c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells struct adapter *adapter = 921c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells container_of(work, struct adapter, ext_intr_handler_task); 9228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 923f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger t1_elmer0_ext_intr_handler(adapter); 9248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* Now reenable external interrupts */ 926559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone spin_lock_irq(&adapter->async_lock); 9278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->slow_intr_mask |= F_PL_INTR_EXT; 928559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE); 929559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, 930205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger adapter->regs + A_PL_ENABLE); 931559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone spin_unlock_irq(&adapter->async_lock); 9328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 9338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter/* 9358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Interrupt-context handler for elmer0 external interrupts. 9368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 9378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_elmer0_ext_intr(struct adapter *adapter) 9388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 9398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 9408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Schedule a task to handle external interrupts as we require 9418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * a process context. We disable EXT interrupts in the interim 9428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * and let the task reenable them when it's done. 9438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 9448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->slow_intr_mask &= ~F_PL_INTR_EXT; 945559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, 946205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger adapter->regs + A_PL_ENABLE); 9478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter schedule_work(&adapter->ext_intr_handler_task); 9488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 9498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametervoid t1_fatal_err(struct adapter *adapter) 9518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 9528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (adapter->flags & FULL_INIT_DONE) { 9538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_sge_stop(adapter->sge); 9548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_interrupts_disable(adapter); 9558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 956c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_alert("%s: encountered fatal error, operation suspended\n", 9578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->name); 9588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 9598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 96080ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemmingerstatic const struct net_device_ops cxgb_netdev_ops = { 96180ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_open = cxgb_open, 96280ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_stop = cxgb_close, 963008298231abbeb91bc7be9e8b078607b816d1a4aStephen Hemminger .ndo_start_xmit = t1_start_xmit, 96480ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_get_stats = t1_get_stats, 96580ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_validate_addr = eth_validate_addr, 966afc4b13df143122f99a0eb10bfefb216c2806de0Jiri Pirko .ndo_set_rx_mode = t1_set_rxmode, 96780ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_do_ioctl = t1_ioctl, 96880ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_change_mtu = t1_change_mtu, 96980ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_set_mac_address = t1_set_mac_addr, 970133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko .ndo_fix_features = t1_fix_features, 971133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko .ndo_set_features = t1_set_features, 97280ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger#ifdef CONFIG_NET_POLL_CONTROLLER 97380ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger .ndo_poll_controller = t1_netpoll, 97480ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger#endif 97580ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger}; 97680ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger 9778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int __devinit init_one(struct pci_dev *pdev, 9788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter const struct pci_device_id *ent) 9798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 9808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter static int version_printed; 9818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter int i, err, pci_using_dac = 0; 9838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter unsigned long mmio_start, mmio_len; 9848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter const struct board_info *bi; 9858199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct adapter *adapter = NULL; 9868199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct port_info *pi; 9878199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9888199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!version_printed) { 989559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION, 990559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone DRV_VERSION); 9918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter ++version_printed; 9928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 9938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = pci_enable_device(pdev); 9958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (err) 996205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger return err; 9978199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 9988199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 999c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: cannot find PCI device memory base address\n", 10008199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_name(pdev)); 10018199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = -ENODEV; 10028199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_disable_pdev; 10038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10056a35528a8346f6e6fd32ed7e51f04d1fa4ca2c01Yang Hongyang if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { 10068199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_using_dac = 1; 1007559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 10086a35528a8346f6e6fd32ed7e51f04d1fa4ca2c01Yang Hongyang if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) { 1009c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: unable to obtain 64-bit DMA for " 10108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter "consistent allocations\n", pci_name(pdev)); 10118199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = -ENODEV; 10128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_disable_pdev; 10138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 1014559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 1015284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang } else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) { 1016c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: no usable DMA configuration\n", pci_name(pdev)); 10178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_disable_pdev; 10188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1020559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone err = pci_request_regions(pdev, DRV_NAME); 10218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (err) { 1022c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: cannot obtain PCI resources\n", pci_name(pdev)); 10238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_disable_pdev; 10248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_set_master(pdev); 10278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1028205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger mmio_start = pci_resource_start(pdev, 0); 10298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter mmio_len = pci_resource_len(pdev, 0); 10308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter bi = t1_get_board_info(ent->driver_data); 10318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter for (i = 0; i < bi->port_number; ++i) { 10338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct net_device *netdev; 10348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter)); 10368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!netdev) { 10378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = -ENOMEM; 10388199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_free_dev; 10398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter SET_NETDEV_DEV(netdev, &pdev->dev); 10428199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!adapter) { 1044c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen adapter = netdev_priv(netdev); 10458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->pdev = pdev; 10468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->port[0].dev = netdev; /* so we don't leak it */ 10478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->regs = ioremap(mmio_start, mmio_len); 10498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!adapter->regs) { 1050c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: cannot map device registers\n", 10518199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_name(pdev)); 10528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = -ENOMEM; 10538199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_free_dev; 10548199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10558199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10568199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (t1_get_board_rev(adapter, bi, &adapter->params)) { 10578199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = -ENODEV; /* Can't handle this chip rev */ 10588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_free_dev; 10598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10618199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->name = pci_name(pdev); 10628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->msg_enable = dflt_msg_enable; 10638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->mmio_len = mmio_len; 10648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock_init(&adapter->tpi_lock); 10668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock_init(&adapter->work_lock); 10678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter spin_lock_init(&adapter->async_lock); 1068352c417ddb593de757f0ee1fa490cb5444778c41Stephen Hemminger spin_lock_init(&adapter->mac_lock); 10698199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter INIT_WORK(&adapter->ext_intr_handler_task, 1071c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells ext_intr_task); 1072c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells INIT_DELAYED_WORK(&adapter->stats_update_task, 1073c4028958b6ecad064b1a6303a6a5906d4fe48d73David Howells mac_stats_task); 10748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_set_drvdata(pdev, netdev); 10768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 10778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 10788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pi = &adapter->port[i]; 10798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pi->dev = netdev; 10808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netif_carrier_off(netdev); 10818199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev->irq = pdev->irq; 10828199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev->if_port = i; 10838199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev->mem_start = mmio_start; 10848199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev->mem_end = mmio_start + mmio_len - 1; 1085c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen netdev->ml_priv = adapter; 108630f554f925335abad89aaa38eec6828242b27527Michał Mirosław netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | 108730f554f925335abad89aaa38eec6828242b27527Michał Mirosław NETIF_F_RXCSUM; 108830f554f925335abad89aaa38eec6828242b27527Michał Mirosław netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | 108930f554f925335abad89aaa38eec6828242b27527Michał Mirosław NETIF_F_RXCSUM | NETIF_F_LLTX; 1090559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone 10918199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (pci_using_dac) 10928199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev->features |= NETIF_F_HIGHDMA; 10938199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (vlan_tso_capable(adapter)) { 10948199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter netdev->features |= 10958199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 1096133b08513a99d44d9ed916bb83e46343f6ad2855Jiri Pirko netdev->hw_features |= NETIF_F_HW_VLAN_RX; 1097f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1098f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* T204: disable TSO */ 1099f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (!(is_T2(adapter)) || bi->port_number != 4) { 110030f554f925335abad89aaa38eec6828242b27527Michał Mirosław netdev->hw_features |= NETIF_F_TSO; 1101f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger netdev->features |= NETIF_F_TSO; 1102f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 11038199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11048199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 110580ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger netdev->netdev_ops = &cxgb_netdev_ops; 110630f554f925335abad89aaa38eec6828242b27527Michał Mirosław netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ? 1107f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt); 110880ff32b76f7969bf62206840c4e1d04674e41df9Stephen Hemminger 1109bea3348eef27e6044b6161fd04c3152215f96411Stephen Hemminger netif_napi_add(netdev, &adapter->napi, t1_poll, 64); 11108199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1111205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); 11128199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11138199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 11148199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (t1_init_sw_modules(adapter, bi) < 0) { 11158199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = -ENODEV; 11168199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_free_dev; 11178199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11188199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 11198199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 11208199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * The card is now ready to go. If any errors occur during device 11218199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * registration we do not fail the whole card but rather proceed only 11228199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * with the ports we manage to register successfully. However we must 11238199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * register at least one net device. 11248199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 11258199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter for (i = 0; i < bi->port_number; ++i) { 11268199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter err = register_netdev(adapter->port[i].dev); 11278199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (err) 1128c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_warning("%s: cannot register net device %s, skipping\n", 1129c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pci_name(pdev), adapter->port[i].dev->name); 11308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter else { 11318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter /* 11328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * Change the name we use for messages to the name of 11338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter * the first successfully registered interface. 11348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter */ 11358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!adapter->registered_device_map) 11368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->name = adapter->port[i].dev->name; 11378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1138205781510d2a55a5c231f6e51df5b6c4aa765143Stephen Hemminger __set_bit(i, &adapter->registered_device_map); 11398199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11418199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (!adapter->registered_device_map) { 1142c1f51212eb809849bdc68a856ae5f424dcf20d9bJoe Perches pr_err("%s: could not register any net devices\n", 11438199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_name(pdev)); 11448199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter goto out_release_adapter_res; 11458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11468199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 11478199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name, 11488199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter bi->desc, adapter->params.chip_revision, 11498199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.pci.is_pcix ? "PCIX" : "PCI", 11508199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter adapter->params.pci.speed, adapter->params.pci.width); 1151f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1152f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* 1153f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger * Set the T1B ASIC and memory clocks. 1154f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger */ 1155f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (t1powersave) 1156f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */ 1157f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger else 1158f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->t1powersave = HCLOCK; 1159f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (t1_is_T1B(adapter)) 1160f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger t1_clock(adapter, t1powersave); 1161f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 11628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return 0; 11638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1164356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieuout_release_adapter_res: 11658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter t1_free_sw_modules(adapter); 1166356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieuout_free_dev: 11678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter if (adapter) { 1168e487647abbe66390b99f9a32ede4688b255282ddStephen Hemminger if (adapter->regs) 1169e487647abbe66390b99f9a32ede4688b255282ddStephen Hemminger iounmap(adapter->regs); 11708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter for (i = bi->port_number - 1; i >= 0; --i) 1171e487647abbe66390b99f9a32ede4688b255282ddStephen Hemminger if (adapter->port[i].dev) 1172e487647abbe66390b99f9a32ede4688b255282ddStephen Hemminger free_netdev(adapter->port[i].dev); 11738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 11748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_release_regions(pdev); 1175356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieuout_disable_pdev: 11768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_disable_device(pdev); 11778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_set_drvdata(pdev, NULL); 11788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter return err; 11798199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 11808199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 1181f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic void bit_bang(struct adapter *adapter, int bitdata, int nbits) 1182f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 1183f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger int data; 1184f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger int i; 1185f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 val; 1186f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1187f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger enum { 1188f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger S_CLOCK = 1 << 3, 1189f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger S_DATA = 1 << 4 1190f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger }; 1191f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1192f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger for (i = (nbits - 1); i > -1; i--) { 1193f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1194f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1195f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1196f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger data = ((bitdata >> i) & 0x1); 1197f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1198f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1199f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (data) 1200f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= S_DATA; 1201f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger else 1202f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_DATA; 1203f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1204f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1205f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1206f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Set SCLOCK low */ 1207f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_CLOCK; 1208f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1209f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1210f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1211f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1212f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Write SCLOCK high */ 1213f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= S_CLOCK; 1214f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1215f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1216f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 1217f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 1218f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1219f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemmingerstatic int t1_clock(struct adapter *adapter, int mode) 1220f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger{ 1221f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger u32 val; 1222f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger int M_CORE_VAL; 1223f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger int M_MEM_VAL; 1224f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1225f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger enum { 1226356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu M_CORE_BITS = 9, 1227356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu T_CORE_VAL = 0, 1228356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu T_CORE_BITS = 2, 1229356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu N_CORE_VAL = 0, 1230356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu N_CORE_BITS = 2, 1231356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu M_MEM_BITS = 9, 1232356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu T_MEM_VAL = 0, 1233356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu T_MEM_BITS = 2, 1234356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu N_MEM_VAL = 0, 1235356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu N_MEM_BITS = 2, 1236356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu NP_LOAD = 1 << 17, 1237356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu S_LOAD_MEM = 1 << 5, 1238356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu S_LOAD_CORE = 1 << 6, 1239356bd1460d1e1c4e433e4114fdac02139bddf17cFrancois Romieu S_CLOCK = 1 << 3 1240f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger }; 1241f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1242f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if (!t1_is_T1B(adapter)) 1243f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return -ENODEV; /* Can't re-clock this chip. */ 1244f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1245d7487421b629c5ca71ce23b10461ef0c3ad2c741Francois Romieu if (mode & 2) 1246f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return 0; /* show current mode. */ 1247f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1248f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if ((adapter->t1powersave & 1) == (mode & 1)) 1249f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return -EALREADY; /* ASIC already running in mode. */ 1250f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1251f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger if ((mode & 1) == HCLOCK) { 1252f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger M_CORE_VAL = 0x14; 1253f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger M_MEM_VAL = 0x18; 1254f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->t1powersave = HCLOCK; /* overclock */ 1255f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } else { 1256f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger M_CORE_VAL = 0xe; 1257f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger M_MEM_VAL = 0x10; 1258f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger adapter->t1powersave = LCLOCK; /* underclock */ 1259f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger } 1260f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1261f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Don't interrupt this serial stream! */ 1262f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger spin_lock(&adapter->tpi_lock); 1263f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1264f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Initialize for ASIC core */ 1265f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1266f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= NP_LOAD; 1267f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1268f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1269f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1270f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1271f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_LOAD_CORE; 1272f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_CLOCK; 1273f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1274f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1275f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1276f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Serial program the ASIC clock synthesizer */ 1277f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger bit_bang(adapter, T_CORE_VAL, T_CORE_BITS); 1278f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger bit_bang(adapter, N_CORE_VAL, N_CORE_BITS); 1279f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger bit_bang(adapter, M_CORE_VAL, M_CORE_BITS); 1280f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1281f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1282f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Finish ASIC core */ 1283f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1284f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= S_LOAD_CORE; 1285f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1286f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1287f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1288f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1289f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_LOAD_CORE; 1290f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1291f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1292f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1293f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1294f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Initialize for memory */ 1295f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1296f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= NP_LOAD; 1297f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1298f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1299f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1300f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1301f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_LOAD_MEM; 1302f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_CLOCK; 1303f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1304f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1305f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1306f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1307f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Serial program the memory clock synthesizer */ 1308f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger bit_bang(adapter, T_MEM_VAL, T_MEM_BITS); 1309f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger bit_bang(adapter, N_MEM_VAL, N_MEM_BITS); 1310f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger bit_bang(adapter, M_MEM_VAL, M_MEM_BITS); 1311f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1312f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1313f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger /* Finish memory */ 1314f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1315f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val |= S_LOAD_MEM; 1316f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1317f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1318f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1319f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_read(adapter, A_ELMER0_GPO, &val); 1320f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger val &= ~S_LOAD_MEM; 1321f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger udelay(50); 1322f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger __t1_tpi_write(adapter, A_ELMER0_GPO, val); 1323f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1324f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger spin_unlock(&adapter->tpi_lock); 1325f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 1326f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger return 0; 1327f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger} 1328f1d3d38af75789f1b82969b83b69cab540609789Stephen Hemminger 13298199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic inline void t1_sw_reset(struct pci_dev *pdev) 13308199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 13318199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3); 13328199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0); 13338199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 13348199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 13358199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void __devexit remove_one(struct pci_dev *pdev) 13368199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 13378199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter struct net_device *dev = pci_get_drvdata(pdev); 1338c3ccc12339afa2633c72131e2aa97d52d9ca1b8aWang Chen struct adapter *adapter = dev->ml_priv; 133947cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu int i; 13408199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 134147cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu for_each_port(adapter, i) { 134247cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu if (test_bit(i, &adapter->registered_device_map)) 134347cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu unregister_netdev(adapter->port[i].dev); 134447cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu } 13458199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 134647cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu t1_free_sw_modules(adapter); 134747cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu iounmap(adapter->regs); 1348e487647abbe66390b99f9a32ede4688b255282ddStephen Hemminger 134947cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu while (--i >= 0) { 135047cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu if (adapter->port[i].dev) 135147cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu free_netdev(adapter->port[i].dev); 13528199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter } 135347cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu 135447cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu pci_release_regions(pdev); 135547cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu pci_disable_device(pdev); 135647cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu pci_set_drvdata(pdev, NULL); 135747cbe6f47d854410d5c296098d87cf8151517c20Francois Romieu t1_sw_reset(pdev); 13588199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 13598199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 13608199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic struct pci_driver driver = { 1361559fb51ba7e66fe298b8355fabde1275b7def35fScott Bardone .name = DRV_NAME, 13628199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .id_table = t1_pci_tbl, 13638199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .probe = init_one, 13648199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter .remove = __devexit_p(remove_one), 13658199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter}; 13668199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 13678199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic int __init t1_init_module(void) 13688199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 1369299176206b266f204be859adf9e66efd06628ab2Jeff Garzik return pci_register_driver(&driver); 13708199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 13718199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 13728199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameterstatic void __exit t1_cleanup_module(void) 13738199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter{ 13748199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter pci_unregister_driver(&driver); 13758199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter} 13768199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lameter 13778199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametermodule_init(t1_init_module); 13788199d3a79c224bbe5943fa08684e1f93a17881b0Christoph Lametermodule_exit(t1_cleanup_module); 1379