+static int
+netxen_loopback_test(struct net_device *netdev, int fint, void *ptr)
+{
+ int ii, ret;
+ unsigned char *data;
+ netxen_send_test_t args;
+
+ if ((ret = copy_from_user(&args, ptr, sizeof(args)))) {
+ return (-LB_UCOPY_PARAM_ERR);
+ }
+
+ if (tx_user_packet_data != NULL) {
+ kfree(tx_user_packet_data);
+ tx_user_packet_data = NULL;
+ }
+
+ if (args.count != 0) { /* user data */
+ tx_user_packet_data = kmalloc(args.count + 16, GFP_KERNEL);
+ if (tx_user_packet_data == NULL)
+ return (-LB_NOMEM_ERR);
+ memset(tx_user_packet_data, 0xFF, 16);
+ /* XXX args.ifg should be u64 */
+ if (copy_from_user(tx_user_packet_data+16,
+ (char *)(uptr_t)args.ifg, args.count)) {
+ kfree(tx_user_packet_data);
+ tx_user_packet_data = NULL;
+ return (-LB_UCOPY_DATA_ERR);
+ }
+ tx_user_packet_length = args.count + 16;
+ rx_datalen = (tx_user_packet_length - 14) * 16;
+ } else { /* use local data */
+ tx_user_packet_data = kmalloc(sizeof(XMIT_DATA) + 16,
GFP_KERNEL);
+ if (tx_user_packet_data == NULL)
+ return (-LB_NOMEM_ERR);
+ memset(tx_user_packet_data, 0xFF, 14);
+ memcpy(tx_user_packet_data + 16, XMIT_DATA, sizeof(XMIT_DATA));
+ tx_user_packet_length = sizeof(XMIT_DATA) + 16;
+ rx_datalen = (sizeof(XMIT_DATA) + 2) * 16;
+ }
+ if ((rx_user_packet_data = kmalloc(rx_datalen, GFP_KERNEL)) == NULL){
+ ret = -LB_NOMEM_ERR;
+ goto end;
+ }
+ rx_user_pos = 0;
+
+ if (fint == 1) {
+ loopback_start = 1;
+ xge_loopback(1);
+ }
+
+ tx_stop = 0;
+ capture_input = 1;
+ captured = 0;
+ args.count = 16;
+ if ((ret = tx_test(netdev, &args)) != 0) {
+ ret = -LB_TX_NOSKB_ERR;
+ capture_input = 0;
+ goto end;
+ }
+
+ mdelay(1000); /* wait for data to come back */
+ capture_input = 0;
+
+ if (rx_user_pos != rx_datalen) {
+ ret = -LB_SHORT_DATA_ERR;
+ goto end;
+ }
+
+ data = rx_user_packet_data;
+ /* check received bytes against tx_user_packet_data */
+ for (ii = 0; ii < 16; ++ii) {
+ if (*((uint16_t *)data) != (uint16_t)ii) {
+ ret = -LB_SEQUENCE_ERR;
+ goto end;
+ }
+ if (memcmp(tx_user_packet_data + 16, data + 2,
+ tx_user_packet_length - 16)
+ != 0) {
+ ret = -LB_DATA_ERR;
+ goto end;
+ }
+ data += (tx_user_packet_length - 14);
+ }
+ ret = LB_TEST_OK;
+
+end:
+ tx_stop = 1;
+ if (fint == 1) {
+ xge_loopback(0);
+ loopback_start = 0;
+ }
+ if (tx_user_packet_data != NULL) {
+ kfree(tx_user_packet_data);
+ tx_user_packet_data = NULL;
+ }
+ kfree(rx_user_packet_data);
+ rx_user_packet_data = NULL;
+ return(ret);
+}
+
+static int
+netxen_link_test(netxen_adapter *adapter)
+{
+ long rv;
+
+ rv = xge_link_status ();
+ return((rv == XG_LINK_DOWN) ? (-1) : (0));
+}
+
+int netxentest_pegstuck(netxen_crbword_t addr, U64 reg, int loop, struct
netxen_adapter_s *adapter)
+{
+ int i;
+ netxen_crbword_t temp;
+
+ for (i = 0; i < loop; ++i) {
+ NetXen_CRB_READ_CHECK_ADAPTER(reg, &temp, adapter);
+ if (temp != addr)
+ return (0);
+ }
+ return (-1);
+}
+
+static int
+netxen_hw_test(netxen_adapter *adapter)
+{
+ netxen_crbword_t temp;
+ int ii, rc = HW_TEST_OK;
+ uint64_t base, address;
+
+ /* DMA Status*/
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_DMA_COMMAND(0), &temp, adapter);
+ if ((temp & 0x3) == 0x3) {
+ rc = -HW_DMA_BZ_0;
+ goto done;
+ }
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_DMA_COMMAND(1), &temp, adapter);
+ if ((temp & 0x3) == 0x3) {
+ rc = -HW_DMA_BZ_1;
+ goto done;
+ }
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_DMA_COMMAND(2), &temp, adapter);
+ if ((temp & 0x3) == 0x3) {
+ rc = -HW_DMA_BZ_2;
+ goto done;
+ }
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_DMA_COMMAND(3), &temp, adapter);
+ if ((temp & 0x3) == 0x3) {
+ rc = -HW_DMA_BZ_3;
+ goto done;
+ }
+
+ /* SRE Status */
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_SRE_PBI_ACTIVE_STATUS, &temp,
adapter);
+ if ((temp & 0x1) == 0) {
+ rc = -HW_SRE_PBI_HALT;
+ goto done;
+ }
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_SRE_L1RE_CTL, &temp, adapter);
+ if ((temp & 0x20000000) != 0) {
+ rc = -HW_SRE_L1IPQ;
+ goto done;
+ }
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_SRE_L2RE_CTL, &temp, adapter);
+ if ((temp & 0x20000000) != 0) {
+ rc = -HW_SRE_L2IFQ;
+ goto done;
+ }
+
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_SRE_INT_STATUS, &temp, adapter);
+ if ((temp & 0xc0ff) != 0) {
+ if ((temp & 0x1) != 0) {
+ rc = -HW_PQ_W_PAUSE;
+ goto done;
+ }
+ if ((temp & 0x2) != 0) {
+ rc = -HW_PQ_W_FULL;
+ goto done;
+ }
+ if ((temp & 0x4) != 0) {
+ rc = -HW_IFQ_W_PAUSE;
+ goto done;
+ }
+ if ((temp & 0x8) != 0) {
+ rc = -HW_IFQ_W_FULL;
+ goto done;
+ }
+ if ((temp & 0x10) != 0) {
+ rc = -HW_MEN_BP_TOUT;
+ goto done;
+ }
+ if ((temp & 0x20) != 0) {
+ rc = -HW_DOWN_BP_TOUT;
+ goto done;
+ }
+ if ((temp & 0x40) != 0) {
+ rc = -HW_FBUFF_POOL_WM;
+ goto done;
+ }
+ if ((temp & 0x80) != 0) {
+ rc = -HW_PBUF_ERR;
+ goto done;
+ }
+ if ((temp & 0x4000) != 0) {
+ rc = -HW_FM_MSG_HDR;
+ goto done;
+ }
+ if ((temp & 0x8000) != 0) {
+ rc = -HW_FM_MSG;
+ goto done;
+ }
+ }
+
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_SRE_INT_STATUS, &temp, adapter);
+
+ if ((temp & 0x3f00) != 0) {
+ if ((temp & 0x100) != 0) {
+ rc = -HW_EPG_MSG_BUF;
+ goto done;
+ }
+ if ((temp & 0x200) != 0) {
+ rc = -HW_EPG_QREAD_TOUT;
+ goto done;
+ }
+ if ((temp & 0x400) != 0) {
+ rc = -HW_EPG_QWRITE_TOUT;
+ goto done;
+ }
+ if ((temp & 0x800) != 0) {
+ rc = -HW_EPG_CQ_W_FULL;
+ goto done;
+ }
+ if ((temp & 0x1000) != 0) {
+ rc = -HW_EPG_MSG_CHKSM;
+ goto done;
+ }
+ if ((temp & 0x2000) != 0) {
+ rc = -HW_EPG_MTLQ_TOUT;
+ goto done;
+ }
+ }
+
+ /* Pegs */
+
+ for (ii = 0; ii < 4; ++ii) {
+ base = PEG_NETWORK_BASE(ii);
+ address = base | CRB_REG_EX_PC;
+ NetXen_CRB_READ_CHECK_ADAPTER(address, &temp, adapter);
+ rc = netxentest_pegstuck(temp, address, PEG_LOOP, adapter);
+ if (rc != 0) {
+ rc = -(HW_PEG0 + ii);
+ goto done;
+ }
+ }
+
+done:
+ return (rc);
+}
+
+static int
+netxen_cis_test(netxen_adapter *adapter)
+{
+ netxen_crbword_t temp, temp1;
+ int ret = CIS_TEST_OK;
+
+ /* Read CAM RAM CRB registers: producer and consumer index for
+ command descriptors. Make sure that P==C or P-C=n0,
+ where n is acceptable number (what range?)*/
+ NetXen_CRB_READ_CHECK_ADAPTER(CRB_CMD_PRODUCER_OFFSET, &temp, adapter);
+ NetXen_CRB_READ_CHECK_ADAPTER(CRB_CMD_CONSUMER_OFFSET, &temp1, adapter);
+
+ if (DIDX_DIF(temp, temp1) > CIS_WATERMARK)
+ ret = -CIS_WMARK;
+ return (ret);
+}
+
+static int
+netxen_cr_test(netxen_adapter *adapter)
+{
+
+ netxen_crbword_t temp;
+ int ret = CR_TEST_OK;
+
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_NIU_MODE, &temp, adapter);
+
+ if ((temp & 0x03) == 0) {
+ ret = -CR_NIU_MODE;
+ goto done;
+ }
+
+ if (adapter->ahw.board_type == NetXen_BRDTYPE_P2_SB31_10G ||
+ adapter->ahw.board_type == NetXen_BRDTYPE_P2_SB31_10G_IMEZ ||
+ adapter->ahw.board_type == NetXen_BRDTYPE_P2_SB31_10G_HMEZ ||
+ adapter->ahw.board_type == NetXen_BRDTYPE_P2_SB31_10G_CX4)
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_NIU_XGE_CONFIG_0, &temp,
adapter);
+ else
+ NetXen_CRB_READ_CHECK_ADAPTER(NetXen_NIU_GB_MAC_CONFIG_0(0), &temp,
adapter);
+
+ if ((temp & 0x5) != 0x5) /* Tx or Rx not enabled */
+ ret = -CR_PHY;
+
+done:
+ return (ret);
+}
+
+/*
+ * netxen_nic_ioctl () We provide the tcl/phanmon support through these
+ * ioctls.
+ */
+static int
+netxen_nic_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+ int err = 0;
+ struct netxen_port *port = netdev->priv;
+ struct netxen_adapter_s *adapter = port->adapter;
+
+ DPRINTK(1, INFO, "doing ioctl for %s\n", netdev->name);
+ switch (cmd) {
+ case NetXen_NIC_CMD:
+ err = netxen_nic_do_ioctl(adapter, (void *) ifr->ifr_data,
port);
+ break;
+
+ case NetXen_NIC_NAME:
+ DPRINTK(1, INFO, "ioctl cmd for NetXen\n");
+ if (ifr->ifr_data) {
+ put_user(port->portnum, (uint16_t *)ifr->ifr_data);
+ }
+ break;
+
+ case NetXen_NIC_SEND_TEST:
+ err = netxen_send_test(netdev, (void
*)ifr->ifr_data);
+ break;
+
+ case NetXen_NIC_IRQ_TEST:
+ err = netxen_irq_test(adapter);
+ break;
+
+ case NetXen_NIC_ILB_TEST:
+ err = netxen_loopback_test(netdev, 1, (void
*)ifr->ifr_data);
+ break;
+
+ case NetXen_NIC_ELB_TEST:
+ err = netxen_loopback_test(netdev, 0, (void
*)ifr->ifr_data);
+ break;
+
+ case NetXen_NIC_LINK_TEST:
+ err = netxen_link_test(adapter);
+ break;
+
+ case NetXen_NIC_HW_TEST:
+ err = netxen_hw_test(adapter);
+ break;
+
+ case NetXen_NIC_CIS_TEST:
+ err = netxen_cis_test(adapter);
+ break;
+
+ case NetXen_NIC_CR_TEST:
+ err = netxen_cr_test(adapter);
+ break;
+
+ default:
+ DPRINTK(1, INFO, "ioctl cmd %x not supported\n", cmd);
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ return err;
+}
+
+static int
+netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct netxen_port *port = netdev->priv;
+
+ netif_device_detach(netdev);
+
+ if(netif_running(netdev)) {
+ netif_carrier_off(netdev);
+ netif_stop_queue(netdev);
+ port->state = PORT_SUSPEND;
+ netxen_nic_down(port);
+ }
+
+/* pci_save_state(pdev, port->pci_state); */
+/* pci_disable_device(pdev); */
+
+ return 0;
+}
+
+static int
+netxen_nic_resume(struct pci_dev *pdev)
+{
+ uint32_t ret;
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct netxen_port *port = netdev->priv;
+ ret = pci_enable_device(pdev);
+ port->state = PORT_UP;
+ netif_device_attach(netdev);
+ return ret;
+}
+
+int
+netxen_nic_fill_statistics(struct netxen_adapter_s *adapter, struct
netxen_port *port,
+ struct netxen_statistics *netxen_stats)
+{
+ unsigned long flags;
+ void* addr;
+ if(adapter->ahw.board_type == NetXen_NIC_XGBE) {
+ write_lock_irqsave(&adapter->adapter_lock, flags);
+ netxen_nic_pci_change_crbwindow(adapter, 0);
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_TX_BYTE_CNT,
&(netxen_stats->tx_bytes));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_TX_FRAME_CNT,
&(netxen_stats->tx_packets));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_RX_BYTE_CNT,
&(netxen_stats->rx_bytes));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_RX_FRAME_CNT,
&(netxen_stats->rx_packets));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_AGGR_ERROR_CNT,
&(netxen_stats->rx_errors));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_CRC_ERROR_CNT,
&(netxen_stats->rx_CRC_errors));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_OVERSIZE_FRAME_ERR,
&(netxen_stats->rx_long_length_error));
+ NetXen_NIC_LOCKED_READ_REG(NetXen_NIU_XGE_UNDERSIZE_FRAME_ERR,
&(netxen_stats->rx_short_length_error));
+
+ /* For reading rx_MAC_error bit different procedure */
+/* NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_TEST_MUX_CTL, 0x15);
+ NetXen_NIC_LOCKED_READ_REG((NetXen_CRB_NIU + 0xC0), &temp);
+ netxen_stats->rx_MAC_errors = temp & 0xff; */
+
+ netxen_nic_pci_change_crbwindow(adapter, 1);
+ write_unlock_irqrestore(&adapter->adapter_lock, flags);
+ } else {
+ spin_lock_bh(&adapter->tx_lock);
+ netxen_stats->tx_bytes = port->stats.txbytes;
+ netxen_stats->tx_packets = port->stats.xmitedframes +
+ port->stats.xmitfinished;
+ netxen_stats->rx_bytes = port->stats.rxbytes;
+ netxen_stats->rx_packets = port->stats.no_rcv;
+ netxen_stats->rx_errors = port->stats.rcvdbadskb;
+ netxen_stats->tx_errors = port->stats.nocmddescriptor;
+ netxen_stats->rx_short_length_error = port->stats.uplcong;
+ netxen_stats->rx_long_length_error = port->stats.uphcong;
+ netxen_stats->rx_CRC_errors = 0;
+ netxen_stats->rx_MAC_errors = 0;
+ spin_unlock_bh(&adapter->tx_lock);
+ }
+ return 0;
+}
+
+int
+netxen_nic_clear_statistics(struct netxen_adapter_s *adapter,
+ struct netxen_port *port)
+{
+ unsigned long flags;
+ void* addr;
+ int data = 0;
+
+ write_lock_irqsave(&adapter->adapter_lock, flags);
+ netxen_nic_pci_change_crbwindow(adapter, 0);
+
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_TX_BYTE_CNT, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_TX_FRAME_CNT, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_RX_BYTE_CNT, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_RX_FRAME_CNT, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_AGGR_ERROR_CNT, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_CRC_ERROR_CNT, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_OVERSIZE_FRAME_ERR, &data);
+ NetXen_NIC_LOCKED_WRITE_REG(NetXen_NIU_XGE_UNDERSIZE_FRAME_ERR, &data);
+
+ netxen_nic_pci_change_crbwindow(adapter, 1);
+ write_unlock_irqrestore(&adapter->adapter_lock, flags);
+ netxen_nic_clear_stats(adapter);
+ return 0;
+}
+static int
+netxen_nic_do_ioctl(struct netxen_adapter_s *adapter, void * u_data,
+ struct netxen_port *port)
+{
+ netxen_nic_ioctl_data_t data;
+ netxen_nic_ioctl_data_t *up_data;
+ int retval = 0;
+ struct netxen_statistics netxen_stats;
+
+ up_data = (void*)u_data;
+
+ DPRINTK(1, INFO, "doing ioctl for %p\n", adapter);
+ if (copy_from_user(&data, up_data, sizeof(data))) {
+ /* evil user tried to crash the kernel */
+ DPRINTK(1, ERR, "bad copy from userland: %d\n",
+ (int)sizeof(data));
+ retval = -EFAULT;
+ goto error_out;
+ }
+
+ /* Shouldn't access beyond legal limits of "char u[64];" member */
+ if (!data.ptr && (data.size > sizeof(data.u))) {
+ /* evil user tried to crash the kernel */
+ DPRINTK(1, ERR, "bad size: %d\n", data.size);
+ retval = -EFAULT;
+ goto error_out;
+ }
+
+ switch (data.cmd) {
+ case netxen_nic_cmd_pci_read:
+ if ((retval = netxen_nic_hw_read_wx(adapter, data.off,
+ &(data.u), data.size)))
+ goto error_out;
+ if (copy_to_user((void*)&(up_data->u), &(data.u),
+ data.size)) {
+ DPRINTK(1, ERR, "bad copy to userland: %d\n",
+ (int)sizeof(data));
+ retval = -EFAULT;
+ goto error_out;
+ }
+ data.rv = 0;
+ break;
+
+ case netxen_nic_cmd_pci_write:
+ data.rv = netxen_nic_hw_write_wx(adapter, data.off, &(data.u),
+ data.size);
+ break;
+
+ case netxen_nic_cmd_pci_mem_read:
+ DPRINTK(1, INFO, "doing %s for %p\n",
"netxen_nic_cmd_pci_mm_rd",
+ adapter);
+ netxen_nic_pci_mem_read(adapter, data.off, &(data.u),
data.size);
+ if (copy_to_user((void*)&(up_data->u), &(data.u), data.size)){
+ DPRINTK(1, ERR, "bad copy to userland: %d\n",
+ (int)sizeof(data));
+ retval = -EFAULT;
+ goto error_out;
+ }
+ data.rv = 0;
+ DPRINTK(1, INFO, "read %lx\n", (unsigned long)data.u);
+ break;
+
+ case netxen_nic_cmd_pci_mem_write:
+ netxen_nic_pci_mem_write(adapter, data.off, &(data.u),
+ data.size);
+ data.rv = 0; /* write always succeeds */
+ break;
+
+ case netxen_nic_cmd_pci_config_read:
+ switch(data.size) {
+ case 1:
+ data.rv = pci_read_config_byte(adapter->ahw.pdev,
+ data.off,
+ (char *)&(data.u));
+ break;
+ case 2:
+ data.rv = pci_read_config_word(adapter->ahw.pdev,
+ data.off,
+ (short *)&(data.u));
+ break;
+ case 4:
+ data.rv = pci_read_config_dword(adapter->ahw.pdev,
+ data.off,
+ (u32 *)&(data.u));
+ break;
+ }
+ if(copy_to_user((void*)&(up_data->u), &(data.u), data.size)) {
+ DPRINTK(1, ERR, "bad copy to userland: %d\n",
+ (int)sizeof(data));
+ retval = -EFAULT;
+ goto error_out;
+ }
+ break;
+
+ case netxen_nic_cmd_pci_config_write:
+ switch(data.size) {
+ case 1:
+ data.rv = pci_write_config_byte(adapter->ahw.pdev,
+ data.off,
+ *(char *)&(data.u));
+ break;
+ case 2:
+ data.rv = pci_write_config_word(adapter->ahw.pdev,
+ data.off,
+ *(short *)&(data.u));
+ break;
+ case 4:
+ data.rv = pci_write_config_dword(adapter->ahw.pdev,
+ data.off,
+ *(u32 *)&(data.u));
+ break;
+ }
+ break;
+
+ case netxen_nic_cmd_get_stats:
+ data.rv = netxen_nic_fill_statistics(adapter, port,
&netxen_stats);
+ if(copy_to_user((void*) (up_data->ptr), (void*)&netxen_stats,
+ sizeof(struct netxen_statistics))) {
+ DPRINTK(1, ERR, "bad copy to userland: %d\n",
+ (int)sizeof(netxen_stats));
+ retval = -EFAULT;
+ goto error_out;
+ }
+ up_data->rv = data.rv;
+ break;
+
+ case netxen_nic_cmd_clear_stats:
+ data.rv = netxen_nic_clear_statistics(adapter, port);
+ up_data->rv = data.rv;
+ break;
+
+ case netxen_nic_cmd_get_version:
+ if(copy_to_user((void*)&(up_data->u),
NetXen_NIC_LINUX_VERSIONID,
+ sizeof(NetXen_NIC_LINUX_VERSIONID))) {
+ DPRINTK(1, ERR, "bad copy to userland: %d\n",
+ (int)sizeof(data));
+ retval = -EFAULT;
+ goto error_out;
+ }
+ break;
+
+
+ default:
+ DPRINTK(1, INFO, "bad command %d for %p\n", data.cmd, adapter);
+ retval = -EOPNOTSUPP;
+ goto error_out;
+ }
+ put_user(data.rv, &(up_data->rv));
+ DPRINTK(1, INFO, "done ioctl for %p well.\n", adapter);
+
+error_out:
+ return retval;
+
+}
+
+static int
+netxen_nic_port_read_proc(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ struct net_device *netdev = (struct net_device *)data;
+ int len = 0;
+ struct netxen_port *port = netdev->priv;
+
+ if (netdev == NULL) {
+ len = sprintf(buf, "No Statistics available now. Device is"
+ " NULL\n");
+ *eof = 1;
+ return len;
+ }
+ len = sprintf(buf, "NetXen NIC port statistics\n");
+ len += sprintf(buf+len, "\n");
+ len += sprintf(buf+len, "Interface Name : %s\n",
+ netdev->name);
+ len += sprintf(buf+len, "Port Number : %d\n",
+ port->portnum);
+ len += sprintf(buf+len, "Bad SKB : %lld\n",
+ port->stats.rcvdbadskb);
+ len += sprintf(buf+len, "Xmit called : %lld\n",
+ port->stats.xmitcalled);
+ len += sprintf(buf+len, "Xmited Frames : %lld\n",
+ port->stats.xmitedframes);
+ len += sprintf(buf+len, "Bad SKB length : %lld\n",
+ port->stats.badskblen);
+ len += sprintf(buf+len, "Cmd Desc Error : %lld\n",
+ port->stats.nocmddescriptor);
+ len += sprintf(buf+len, "Polled for Rcv : %lld\n",
+ port->stats.polled);
+ len += sprintf(buf+len, "Recieved Desc : %lld\n",
+ port->stats.no_rcv);
+ len += sprintf(buf+len, "Rcv to stack : %lld\n",
+ port->stats.uphappy);
+ len += sprintf(buf+len, "Stack dropped : %lld\n",
+ port->stats.updropped);
+ len += sprintf(buf+len, "Low congestion : %lld\n",
+ port->stats.uplcong);
+ len += sprintf(buf+len, "High congestion : %lld\n",
+ port->stats.uphcong);
+ len += sprintf(buf+len, "Medium congestion : %lld\n",
+ port->stats.upmcong);
+ len += sprintf(buf+len, "Rcv bad return : %lld\n",
+ port->stats.updunno);
+ len += sprintf(buf+len, "SKBs Freed : %lld\n",
+ port->stats.skbfreed);
+ len += sprintf(buf+len, "Xmit finished : %lld\n",
+ port->stats.xmitfinished);
+ len += sprintf(buf+len, "Tx dropped SKBs : %lld\n",
+ port->stats.txdropped);
+ len += sprintf(buf+len, "Tx got NULL SKBs : %lld\n",
+ port->stats.txnullskb);
+ len += sprintf(buf+len, "Rcv of CSUMed SKB : %lld\n",
+ port->stats.csummed);
+ len += sprintf(buf+len, "\n");
+ *eof = 1;
+ return len;
+}
+
+/* /proc interface to export debug info to the userland */
+static int
+netxen_nic_read_proc(char *buf, char **start, off_t offset, int count,int *eof,
+ void *data)
+{
+ struct netxen_adapter_s *adapter = (struct netxen_adapter_s *)data;
+ int i, j;
+ int len = 0;
+
+ if (adapter == NULL) {
+ len = sprintf(buf, "No Statistics available now."
+ " Adapter is NULL\n");
+ *eof = 1;
+ return len;
+ }
+ len = sprintf(buf, "NetXen NIC statistics\n");
+ len += sprintf(buf+len, "\n");
+ len += sprintf(buf+len, "Ring Statistics\n");
+ len += sprintf(buf+len, "Command Producer : %d\n",
+ adapter->cmdProducer);
+ len += sprintf(buf+len, "LastCommand Consumer: %d\n",
+ adapter->lastCmdConsumer);
+ for (i = 0; i < MAX_RCV_CTX; ++i) {
+ for (j = 0; j < NUM_RCV_DESC_RINGS; j++) {
+ len += sprintf(buf+len, "Rcv Ring %d\n", j);
+ len += sprintf(buf+len, "\tRecieve Producer [%d]:"
+ " %d\n", i,
+ adapter->recv_ctx[i].rcv_desc[j].producer);
+ }
+ len += sprintf(buf+len, "Status(Rcv) Producer[%d]: %d\n",
+ i, adapter->recv_ctx[i].statusRxProducer);
+ len += sprintf(buf+len, "Status(Rcv) Consumer[%d]: %d\n",
+ i, adapter->recv_ctx[i].statusRxConsumer);
+ }
+ len += sprintf(buf+len, "\n");
+ len += sprintf(buf+len, "Adapter Statistics\n");
+ len += sprintf(buf+len, "Interrupts : %lld\n",
+ adapter->stats.ints);
+ len += sprintf(buf+len, "Host Interrupts : %lld\n",
+ adapter->stats.hostints);
+ len += sprintf(buf+len, "Other Interrupts: %lld\n",
+ adapter->stats.otherints);
+ len += sprintf(buf+len, "Recieve Events : %lld\n",
+ adapter->stats.process_rcv);
+ len += sprintf(buf+len, "Transmit : %lld\n",
+ adapter->stats.process_xmit);
+ len += sprintf(buf+len, "No Transmit : %lld\n",
+ adapter->stats.noxmitdone);
+ len += sprintf(buf+len, "Xmit csummed : %lld\n",
+ adapter->stats.xmitcsummed);
+ len += sprintf(buf+len, "Posted : %lld\n",
+ adapter->stats.post_called);
+ len += sprintf(buf+len, "Posted : %lld\n",
+ adapter->stats.posted);
+ len += sprintf(buf+len, "Last post count : %lld\n",
+ adapter->stats.lastposted);
+ for (i = 0; i < MAX_RCV_CTX; ++i) {
+ for (j = 0; j < NUM_RCV_DESC_RINGS; j++) {
+ len += sprintf(buf+len, "Rcv Ring %d\n", j);
+ len += sprintf(buf+len, "\tfree Rx buffers[%d] : %d\n",
+ i,
+ adapter->recv_ctx[i].rcv_desc[j].rcv_free);
+ len += sprintf(buf+len, "\tpending Rx[%d] : %d\n",
+ i,
+ adapter->recv_ctx[i].rcv_desc[j].rcv_pending);
+ }
+ }
+ len += sprintf(buf+len, "Pending Cmd cnt : %d\n",
+ adapter->pendingCmdCount);
+ len += sprintf(buf+len, "Free Cmd Count : %d\n",
+ adapter->freeCmdCount);
+ len += sprintf(buf+len, "Good SKB posts : %lld\n",
+ adapter->stats.goodskbposts);
+ *eof = 1;
+ return len;
+}
+
+static struct pci_driver netxen_driver = {
+ .name = netxen_nic_driver_name,
+ .id_table = netxen_pci_tbl,
+ .probe = netxen_nic_probe,
+ .remove = __devexit_p(netxen_nic_remove),
+ .suspend = netxen_nic_suspend,
+ .resume = netxen_nic_resume
+};
+
+/* Driver Registration on NetXen card */
+
+static int __init
+netxen_init_module(void)
+{
+ int i;
+ printk(KERN_INFO "%s \n", netxen_nic_driver_string);
+ netxen_proc_dir_entry = proc_mkdir(netxen_nic_driver_name, proc_net);
+ if (!netxen_proc_dir_entry) {
+ printk(KERN_WARNING "%s: Unable to create /proc/net/%s",
+ netxen_nic_driver_name, netxen_nic_driver_name);
+ return -ENOMEM;
+ }
+ netxen_proc_dir_entry->owner = THIS_MODULE;
+
+ cmd_desc_cache = kmem_cache_create("cmd_desc_cache",
+ sizeof(cmdDescType0_t) * ((MAX_BUFFERS_PER_CMD/4)+3),
+ ARCH_KMALLOC_MINALIGN, ARCH_KMALLOC_FLAGS, NULL, NULL);
+ cmd_buff_cache = kmem_cache_create("cmd_buff_cache",
+ sizeof(struct netxen_cmd_buffer), ARCH_KMALLOC_MINALIGN,
+ ARCH_KMALLOC_FLAGS, NULL, NULL);
+ for (i=0; i<NR_CPUS; i++) {
+ cmd_desc_array[i] =
+ (cmdDescType0_t *) kmem_cache_alloc (cmd_desc_cache,
+ SLAB_ATOMIC);
+ cmd_buff_array[i] =
+ (struct netxen_cmd_buffer *) kmem_cache_alloc
(cmd_buff_cache,
+ SLAB_ATOMIC);
+ }
+
+ pci_module_init(&netxen_driver);
+
+ if (netxen_nic_probe_err != 0) {
+ for (i=0; i<NR_CPUS; i++) {
+ if (cmd_desc_array[i])
+ kmem_cache_free(cmd_desc_cache,
+ cmd_desc_array[i]);
+ if (cmd_buff_array[i])
+ kmem_cache_free(cmd_buff_cache,
+ cmd_buff_array[i]);
+ }
+ kmem_cache_destroy(cmd_desc_cache);
+ kmem_cache_destroy(cmd_buff_cache);
+ remove_proc_entry(netxen_proc_dir_entry->name, proc_net);
+ }
+ return netxen_nic_probe_err;
+}
+
+module_init(netxen_init_module);
+
+static void __exit
+netxen_exit_module(void)
+{
+ int i;
+ struct netxen_adapter_s *adapter;
+
+ if (tx_user_packet_data != NULL) {
+ kfree(tx_user_packet_data);
+ tx_user_packet_data = NULL;
+ tx_user_packet_length = 0;
+ }
+ for(i=0; i<MAX_NUM_CARDS; i++)
+ {
+ adapter = adapterlist[i];
+ if (adapter == NULL)
+ continue;
+ if (adapter->netlist != NULL && adapter->netlist->netdev !=
NULL) {
+/* struct net_device *netdev = netxen_netlist->netdev;
+ struct netxen_port *port = netdev->priv;
+ struct netxen_adapter_s *adapter = port->adapter;
+*/
+ read_lock(&adapter->adapter_lock);
+ netxen_nic_disable_int(adapter);
+ read_unlock(&adapter->adapter_lock);
+ pinit_from_rom(adapter, 0);
+ }
+ }
+
+ /*
+ * Wait for some time to allow the dma to drain, if any.
+ */
+ mdelay(5);
+ pci_unregister_driver(&netxen_driver);
+ remove_proc_entry(netxen_proc_dir_entry->name, proc_net);
+ for (i=0; i<NR_CPUS; i++) {
+ if (cmd_desc_array[i])
+ kmem_cache_free(cmd_desc_cache, cmd_desc_array[i]);
+ if (cmd_buff_array[i])
+ kmem_cache_free(cmd_buff_cache, cmd_buff_array[i]);
+ }
+ kmem_cache_destroy(cmd_desc_cache);
+ kmem_cache_destroy(cmd_buff_cache);
+}
+module_exit(netxen_exit_module);
+
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html