Lines Matching +full:100 +full:base +full:- +full:fx
3 Written 2002-2004 by David Dillow <dave@thedillows.org>
4 Based on code written 1998-2000 by Donald Becker <becker@scyld.com> and
21 number Y1-LM-2015-01.
29 *) Waiting for a command response takes 8ms due to non-preemptable
41 http://oss.sgi.com/cgi-bin/mesg.cgi?a=netdev&i=20031215152211.7003fe8e.rddunlap%40osdl.org
44 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
56 /* end user-configurable values */
58 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
68 * There are no ill effects from too-large receive rings.
89 #define RXENT_ENTRIES (RXFREE_ENTRIES - 1)
124 #include <linux/dma-mapping.h>
166 { "3Com Typhoon (3C990-TX)",
168 { "3Com Typhoon (3CR990-TX-95)",
170 { "3Com Typhoon (3CR990-TX-97)",
178 { "3Com Typhoon2 (3C990B-TX-M)",
182 { "3Com Typhoon (3CR990-FX-95)",
184 { "3Com Typhoon (3CR990-FX-97)",
186 { "3Com Typhoon (3CR990-FX-95 Server)",
188 { "3Com Typhoon (3CR990-FX-97 Server)",
190 { "3Com Typhoon2 (3C990B-FX-97)",
195 * bits 0-1 indicate crypto capabilities: (0) variable, (1) DES, or (2) 3DES
198 * bits 12-16 indicate card type: (0) client and (1) server
318 #define skb_tso_size(x) (skb_shinfo(x)->gso_size)
331 /* Increment a ring index -- we can use this for all rings execept in typhoon_inc_index()
403 err = -ETIMEDOUT; in typhoon_reset()
417 * which should be enough (I've see it work well at 100us, but still in typhoon_reset()
438 err = -ETIMEDOUT; in typhoon_wait_status()
447 if (resp->parm1 & TYPHOON_MEDIA_STAT_NO_LINK) in typhoon_media_status()
456 struct basic_ring *ring = &tp->cmdRing; in typhoon_hello()
463 if (spin_trylock(&tp->command_lock)) { in typhoon_hello()
464 cmd = (struct cmd_desc *)(ring->ringBase + ring->lastWrite); in typhoon_hello()
465 typhoon_inc_cmd_index(&ring->lastWrite, 1); in typhoon_hello()
469 iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); in typhoon_hello()
470 spin_unlock(&tp->command_lock); in typhoon_hello()
478 struct typhoon_indexes *indexes = tp->indexes; in typhoon_process_response()
480 u8 *base = tp->respRing.ringBase; in typhoon_process_response() local
485 cleared = le32_to_cpu(indexes->respCleared); in typhoon_process_response()
486 ready = le32_to_cpu(indexes->respReady); in typhoon_process_response()
488 resp = (struct resp_desc *)(base + cleared); in typhoon_process_response()
489 count = resp->numDesc + 1; in typhoon_process_response()
490 if (resp_save && resp->seqNo) { in typhoon_process_response()
492 resp_save->flags = TYPHOON_RESP_ERROR; in typhoon_process_response()
499 wrap_len = cleared + len - RESPONSE_RING_SIZE; in typhoon_process_response()
500 len = RESPONSE_RING_SIZE - cleared; in typhoon_process_response()
506 memcpy(resp_save, base, wrap_len); in typhoon_process_response()
510 } else if (resp->cmd == TYPHOON_CMD_READ_MEDIA_STATUS) { in typhoon_process_response()
511 typhoon_media_status(tp->dev, resp); in typhoon_process_response()
512 } else if (resp->cmd == TYPHOON_CMD_HELLO_RESP) { in typhoon_process_response()
515 netdev_err(tp->dev, in typhoon_process_response()
517 le16_to_cpu(resp->cmd), in typhoon_process_response()
518 resp->numDesc, resp->flags, in typhoon_process_response()
519 le16_to_cpu(resp->parm1), in typhoon_process_response()
520 le32_to_cpu(resp->parm2), in typhoon_process_response()
521 le32_to_cpu(resp->parm3)); in typhoon_process_response()
528 indexes->respCleared = cpu_to_le32(cleared); in typhoon_process_response()
537 * different size than the cmd_desc -- everyone else is the same in typhoon_num_free()
541 return (ringSize + lastRead - lastWrite - 1) % ringSize; in typhoon_num_free()
547 int lastWrite = tp->cmdRing.lastWrite; in typhoon_num_free_cmd()
548 int cmdCleared = le32_to_cpu(tp->indexes->cmdCleared); in typhoon_num_free_cmd()
556 int respReady = le32_to_cpu(tp->indexes->respReady); in typhoon_num_free_resp()
557 int respCleared = le32_to_cpu(tp->indexes->respCleared); in typhoon_num_free_resp()
566 return typhoon_num_free(ring->lastWrite, ring->lastRead, TXLO_ENTRIES); in typhoon_num_free_tx()
573 struct typhoon_indexes *indexes = tp->indexes; in typhoon_issue_command()
574 struct basic_ring *ring = &tp->cmdRing; in typhoon_issue_command()
581 spin_lock(&tp->command_lock); in typhoon_issue_command()
587 netdev_err(tp->dev, "no descs for cmd, had (needed) %d (%d) cmd, %d (%d) resp\n", in typhoon_issue_command()
589 err = -ENOMEM; in typhoon_issue_command()
593 if (cmd->flags & TYPHOON_CMD_RESPOND) { in typhoon_issue_command()
597 tp->awaiting_resp = 1; in typhoon_issue_command()
606 if (unlikely(ring->lastWrite + len > COMMAND_RING_SIZE)) { in typhoon_issue_command()
607 wrap_len = ring->lastWrite + len - COMMAND_RING_SIZE; in typhoon_issue_command()
608 len = COMMAND_RING_SIZE - ring->lastWrite; in typhoon_issue_command()
611 memcpy(ring->ringBase + ring->lastWrite, cmd, len); in typhoon_issue_command()
615 memcpy(ring->ringBase, wrap_ptr, wrap_len); in typhoon_issue_command()
618 typhoon_inc_cmd_index(&ring->lastWrite, num_cmd); in typhoon_issue_command()
623 iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); in typhoon_issue_command()
624 typhoon_post_pci_writes(tp->ioaddr); in typhoon_issue_command()
626 if ((cmd->flags & TYPHOON_CMD_RESPOND) == 0) in typhoon_issue_command()
635 * 3Com has implemented irq coalescing, we would likely timeout -- in typhoon_issue_command()
647 if (indexes->respCleared != indexes->respReady) in typhoon_issue_command()
654 err = -ETIMEDOUT; in typhoon_issue_command()
661 if (resp->flags & TYPHOON_RESP_ERROR) in typhoon_issue_command()
662 err = -EIO; in typhoon_issue_command()
665 if (tp->awaiting_resp) { in typhoon_issue_command()
666 tp->awaiting_resp = 0; in typhoon_issue_command()
671 * of tp->awaiting_resp, we could have missed the interrupt in typhoon_issue_command()
676 if (indexes->respCleared != indexes->respReady) in typhoon_issue_command()
677 iowrite32(1, tp->ioaddr + TYPHOON_REG_SELF_INTERRUPT); in typhoon_issue_command()
680 spin_unlock(&tp->command_lock); in typhoon_issue_command()
691 tcpd = (struct tcpopt_desc *) (txRing->ringBase + txRing->lastWrite); in typhoon_tso_fill()
692 tcpd_offset += txRing->lastWrite; in typhoon_tso_fill()
694 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_tso_fill()
696 tcpd->flags = TYPHOON_OPT_DESC | TYPHOON_OPT_TCP_SEG; in typhoon_tso_fill()
697 tcpd->numDesc = 1; in typhoon_tso_fill()
698 tcpd->mss_flags = cpu_to_le16(skb_tso_size(skb)); in typhoon_tso_fill()
699 tcpd->mss_flags |= TYPHOON_TSO_FIRST | TYPHOON_TSO_LAST; in typhoon_tso_fill()
700 tcpd->respAddrLo = cpu_to_le32(tcpd_offset); in typhoon_tso_fill()
701 tcpd->bytesTx = cpu_to_le32(skb->len); in typhoon_tso_fill()
702 tcpd->status = 0; in typhoon_tso_fill()
720 txRing = &tp->txLoRing; in typhoon_start_tx()
723 * one for the ->data area of it. in typhoon_start_tx()
733 numDesc = skb_shinfo(skb)->nr_frags + 1; in typhoon_start_tx()
749 first_txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); in typhoon_start_tx()
750 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_start_tx()
752 first_txd->flags = TYPHOON_TX_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
753 first_txd->numDesc = 0; in typhoon_start_tx()
754 first_txd->len = 0; in typhoon_start_tx()
755 first_txd->tx_addr = (u64)((unsigned long) skb); in typhoon_start_tx()
756 first_txd->processFlags = 0; in typhoon_start_tx()
758 if (skb->ip_summed == CHECKSUM_PARTIAL) { in typhoon_start_tx()
760 first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM; in typhoon_start_tx()
761 first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM; in typhoon_start_tx()
762 first_txd->processFlags |= TYPHOON_TX_PF_IP_CHKSUM; in typhoon_start_tx()
766 first_txd->processFlags |= in typhoon_start_tx()
768 first_txd->processFlags |= in typhoon_start_tx()
774 first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT; in typhoon_start_tx()
775 first_txd->numDesc++; in typhoon_start_tx()
777 typhoon_tso_fill(skb, txRing, tp->txlo_dma_addr); in typhoon_start_tx()
780 txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); in typhoon_start_tx()
781 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_start_tx()
783 /* No need to worry about padding packet -- the firmware pads in typhoon_start_tx()
786 if (skb_shinfo(skb)->nr_frags == 0) { in typhoon_start_tx()
787 skb_dma = dma_map_single(&tp->tx_pdev->dev, skb->data, in typhoon_start_tx()
788 skb->len, DMA_TO_DEVICE); in typhoon_start_tx()
789 txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
790 txd->len = cpu_to_le16(skb->len); in typhoon_start_tx()
791 txd->frag.addr = cpu_to_le32(skb_dma); in typhoon_start_tx()
792 txd->frag.addrHi = 0; in typhoon_start_tx()
793 first_txd->numDesc++; in typhoon_start_tx()
798 skb_dma = dma_map_single(&tp->tx_pdev->dev, skb->data, len, in typhoon_start_tx()
800 txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
801 txd->len = cpu_to_le16(len); in typhoon_start_tx()
802 txd->frag.addr = cpu_to_le32(skb_dma); in typhoon_start_tx()
803 txd->frag.addrHi = 0; in typhoon_start_tx()
804 first_txd->numDesc++; in typhoon_start_tx()
806 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { in typhoon_start_tx()
807 const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; in typhoon_start_tx()
810 txd = (struct tx_desc *) (txRing->ringBase + in typhoon_start_tx()
811 txRing->lastWrite); in typhoon_start_tx()
812 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_start_tx()
816 skb_dma = dma_map_single(&tp->tx_pdev->dev, frag_addr, in typhoon_start_tx()
818 txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
819 txd->len = cpu_to_le16(len); in typhoon_start_tx()
820 txd->frag.addr = cpu_to_le32(skb_dma); in typhoon_start_tx()
821 txd->frag.addrHi = 0; in typhoon_start_tx()
822 first_txd->numDesc++; in typhoon_start_tx()
829 iowrite32(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister); in typhoon_start_tx()
833 * descriptors -- one to prevent ring wrap, and one for the in typhoon_start_tx()
861 if (dev->flags & IFF_PROMISC) { in typhoon_set_rx_mode()
864 (dev->flags & IFF_ALLMULTI)) { in typhoon_set_rx_mode()
872 int bit = ether_crc(ETH_ALEN, ha->addr) & 0x3f; in typhoon_set_rx_mode()
894 struct net_device_stats *stats = &tp->dev->stats; in typhoon_do_get_stats()
895 struct net_device_stats *saved = &tp->stats_saved; in typhoon_do_get_stats()
910 * ethtool_ops->get_{strings,stats}() in typhoon_do_get_stats()
912 stats->tx_packets = le32_to_cpu(s->txPackets) + in typhoon_do_get_stats()
913 saved->tx_packets; in typhoon_do_get_stats()
914 stats->tx_bytes = le64_to_cpu(s->txBytes) + in typhoon_do_get_stats()
915 saved->tx_bytes; in typhoon_do_get_stats()
916 stats->tx_errors = le32_to_cpu(s->txCarrierLost) + in typhoon_do_get_stats()
917 saved->tx_errors; in typhoon_do_get_stats()
918 stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) + in typhoon_do_get_stats()
919 saved->tx_carrier_errors; in typhoon_do_get_stats()
920 stats->collisions = le32_to_cpu(s->txMultipleCollisions) + in typhoon_do_get_stats()
921 saved->collisions; in typhoon_do_get_stats()
922 stats->rx_packets = le32_to_cpu(s->rxPacketsGood) + in typhoon_do_get_stats()
923 saved->rx_packets; in typhoon_do_get_stats()
924 stats->rx_bytes = le64_to_cpu(s->rxBytesGood) + in typhoon_do_get_stats()
925 saved->rx_bytes; in typhoon_do_get_stats()
926 stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) + in typhoon_do_get_stats()
927 saved->rx_fifo_errors; in typhoon_do_get_stats()
928 stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + in typhoon_do_get_stats()
929 le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) + in typhoon_do_get_stats()
930 saved->rx_errors; in typhoon_do_get_stats()
931 stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) + in typhoon_do_get_stats()
932 saved->rx_crc_errors; in typhoon_do_get_stats()
933 stats->rx_length_errors = le32_to_cpu(s->rxOversized) + in typhoon_do_get_stats()
934 saved->rx_length_errors; in typhoon_do_get_stats()
935 tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? in typhoon_do_get_stats()
937 tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? in typhoon_do_get_stats()
947 struct net_device_stats *stats = &tp->dev->stats; in typhoon_get_stats()
948 struct net_device_stats *saved = &tp->stats_saved; in typhoon_get_stats()
951 if (tp->card_state == Sleeping) in typhoon_get_stats()
966 struct pci_dev *pci_dev = tp->pdev; in typhoon_get_drvinfo()
971 if (tp->card_state == Sleeping) { in typhoon_get_drvinfo()
972 strscpy(info->fw_version, "Sleep image", in typhoon_get_drvinfo()
973 sizeof(info->fw_version)); in typhoon_get_drvinfo()
977 strscpy(info->fw_version, "Unknown runtime", in typhoon_get_drvinfo()
978 sizeof(info->fw_version)); in typhoon_get_drvinfo()
981 snprintf(info->fw_version, sizeof(info->fw_version), in typhoon_get_drvinfo()
987 strscpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); in typhoon_get_drvinfo()
988 strscpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); in typhoon_get_drvinfo()
1001 switch (tp->xcvr_select) { in typhoon_get_link_ksettings()
1023 if (tp->capabilities & TYPHOON_FIBER) { in typhoon_get_link_ksettings()
1026 cmd->base.port = PORT_FIBRE; in typhoon_get_link_ksettings()
1032 cmd->base.port = PORT_TP; in typhoon_get_link_ksettings()
1037 cmd->base.speed = tp->speed; in typhoon_get_link_ksettings()
1038 cmd->base.duplex = tp->duplex; in typhoon_get_link_ksettings()
1039 cmd->base.phy_address = 0; in typhoon_get_link_ksettings()
1040 if (tp->xcvr_select == TYPHOON_XCVR_AUTONEG) in typhoon_get_link_ksettings()
1041 cmd->base.autoneg = AUTONEG_ENABLE; in typhoon_get_link_ksettings()
1043 cmd->base.autoneg = AUTONEG_DISABLE; in typhoon_get_link_ksettings()
1045 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, in typhoon_get_link_ksettings()
1047 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, in typhoon_get_link_ksettings()
1058 u32 speed = cmd->base.speed; in typhoon_set_link_ksettings()
1063 err = -EINVAL; in typhoon_set_link_ksettings()
1064 if (cmd->base.autoneg == AUTONEG_ENABLE) { in typhoon_set_link_ksettings()
1067 if (cmd->base.duplex == DUPLEX_HALF) { in typhoon_set_link_ksettings()
1074 } else if (cmd->base.duplex == DUPLEX_FULL) { in typhoon_set_link_ksettings()
1091 tp->xcvr_select = xcvr; in typhoon_set_link_ksettings()
1092 if (cmd->base.autoneg == AUTONEG_ENABLE) { in typhoon_set_link_ksettings()
1093 tp->speed = 0xff; /* invalid */ in typhoon_set_link_ksettings()
1094 tp->duplex = 0xff; /* invalid */ in typhoon_set_link_ksettings()
1096 tp->speed = speed; in typhoon_set_link_ksettings()
1097 tp->duplex = cmd->base.duplex; in typhoon_set_link_ksettings()
1109 wol->supported = WAKE_PHY | WAKE_MAGIC; in typhoon_get_wol()
1110 wol->wolopts = 0; in typhoon_get_wol()
1111 if (tp->wol_events & TYPHOON_WAKE_LINK_EVENT) in typhoon_get_wol()
1112 wol->wolopts |= WAKE_PHY; in typhoon_get_wol()
1113 if (tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) in typhoon_get_wol()
1114 wol->wolopts |= WAKE_MAGIC; in typhoon_get_wol()
1115 memset(&wol->sopass, 0, sizeof(wol->sopass)); in typhoon_get_wol()
1123 if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC)) in typhoon_set_wol()
1124 return -EINVAL; in typhoon_set_wol()
1126 tp->wol_events = 0; in typhoon_set_wol()
1127 if (wol->wolopts & WAKE_PHY) in typhoon_set_wol()
1128 tp->wol_events |= TYPHOON_WAKE_LINK_EVENT; in typhoon_set_wol()
1129 if (wol->wolopts & WAKE_MAGIC) in typhoon_set_wol()
1130 tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT; in typhoon_set_wol()
1140 ering->rx_max_pending = RXENT_ENTRIES; in typhoon_get_ringparam()
1141 ering->tx_max_pending = TXLO_ENTRIES - 1; in typhoon_get_ringparam()
1143 ering->rx_pending = RXENT_ENTRIES; in typhoon_get_ringparam()
1144 ering->tx_pending = TXLO_ENTRIES - 1; in typhoon_get_ringparam()
1169 err = -ETIMEDOUT; in typhoon_wait_interrupt()
1181 struct typhoon_interface *iface = &tp->shared->iface; in typhoon_init_interface()
1184 memset(tp->shared, 0, sizeof(struct typhoon_shared)); in typhoon_init_interface()
1188 shared_dma = tp->shared_dma + shared_offset(indexes); in typhoon_init_interface()
1189 iface->ringIndex = cpu_to_le32(shared_dma); in typhoon_init_interface()
1191 shared_dma = tp->shared_dma + shared_offset(txLo); in typhoon_init_interface()
1192 iface->txLoAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1193 iface->txLoSize = cpu_to_le32(TXLO_ENTRIES * sizeof(struct tx_desc)); in typhoon_init_interface()
1195 shared_dma = tp->shared_dma + shared_offset(txHi); in typhoon_init_interface()
1196 iface->txHiAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1197 iface->txHiSize = cpu_to_le32(TXHI_ENTRIES * sizeof(struct tx_desc)); in typhoon_init_interface()
1199 shared_dma = tp->shared_dma + shared_offset(rxBuff); in typhoon_init_interface()
1200 iface->rxBuffAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1201 iface->rxBuffSize = cpu_to_le32(RXFREE_ENTRIES * in typhoon_init_interface()
1204 shared_dma = tp->shared_dma + shared_offset(rxLo); in typhoon_init_interface()
1205 iface->rxLoAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1206 iface->rxLoSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); in typhoon_init_interface()
1208 shared_dma = tp->shared_dma + shared_offset(rxHi); in typhoon_init_interface()
1209 iface->rxHiAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1210 iface->rxHiSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); in typhoon_init_interface()
1212 shared_dma = tp->shared_dma + shared_offset(cmd); in typhoon_init_interface()
1213 iface->cmdAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1214 iface->cmdSize = cpu_to_le32(COMMAND_RING_SIZE); in typhoon_init_interface()
1216 shared_dma = tp->shared_dma + shared_offset(resp); in typhoon_init_interface()
1217 iface->respAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1218 iface->respSize = cpu_to_le32(RESPONSE_RING_SIZE); in typhoon_init_interface()
1220 shared_dma = tp->shared_dma + shared_offset(zeroWord); in typhoon_init_interface()
1221 iface->zeroAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1223 tp->indexes = &tp->shared->indexes; in typhoon_init_interface()
1224 tp->txLoRing.ringBase = (u8 *) tp->shared->txLo; in typhoon_init_interface()
1225 tp->txHiRing.ringBase = (u8 *) tp->shared->txHi; in typhoon_init_interface()
1226 tp->rxLoRing.ringBase = (u8 *) tp->shared->rxLo; in typhoon_init_interface()
1227 tp->rxHiRing.ringBase = (u8 *) tp->shared->rxHi; in typhoon_init_interface()
1228 tp->rxBuffRing.ringBase = (u8 *) tp->shared->rxBuff; in typhoon_init_interface()
1229 tp->cmdRing.ringBase = (u8 *) tp->shared->cmd; in typhoon_init_interface()
1230 tp->respRing.ringBase = (u8 *) tp->shared->resp; in typhoon_init_interface()
1232 tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY; in typhoon_init_interface()
1233 tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY; in typhoon_init_interface()
1235 tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); in typhoon_init_interface()
1236 tp->card_state = Sleeping; in typhoon_init_interface()
1238 tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; in typhoon_init_interface()
1239 tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; in typhoon_init_interface()
1240 tp->offload |= TYPHOON_OFFLOAD_VLAN; in typhoon_init_interface()
1242 spin_lock_init(&tp->command_lock); in typhoon_init_interface()
1251 memset(tp->indexes, 0, sizeof(struct typhoon_indexes)); in typhoon_init_rings()
1253 tp->txLoRing.lastWrite = 0; in typhoon_init_rings()
1254 tp->txHiRing.lastWrite = 0; in typhoon_init_rings()
1255 tp->rxLoRing.lastWrite = 0; in typhoon_init_rings()
1256 tp->rxHiRing.lastWrite = 0; in typhoon_init_rings()
1257 tp->rxBuffRing.lastWrite = 0; in typhoon_init_rings()
1258 tp->cmdRing.lastWrite = 0; in typhoon_init_rings()
1259 tp->respRing.lastWrite = 0; in typhoon_init_rings()
1261 tp->txLoRing.lastRead = 0; in typhoon_init_rings()
1262 tp->txHiRing.lastRead = 0; in typhoon_init_rings()
1281 err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); in typhoon_request_firmware()
1283 netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", in typhoon_request_firmware()
1288 image_data = typhoon_fw->data; in typhoon_request_firmware()
1289 remaining = typhoon_fw->size; in typhoon_request_firmware()
1294 if (memcmp(fHdr->tag, "TYPHOON", 8)) in typhoon_request_firmware()
1297 numSections = le32_to_cpu(fHdr->numSections); in typhoon_request_firmware()
1299 remaining -= sizeof(struct typhoon_file_header); in typhoon_request_firmware()
1301 while (numSections--) { in typhoon_request_firmware()
1307 section_len = le32_to_cpu(sHdr->len); in typhoon_request_firmware()
1313 remaining -= section_len; in typhoon_request_firmware()
1319 netdev_err(tp->dev, "Invalid firmware image\n"); in typhoon_request_firmware()
1322 return -EINVAL; in typhoon_request_firmware()
1328 void __iomem *ioaddr = tp->ioaddr; in typhoon_download_firmware()
1329 struct pci_dev *pdev = tp->pdev; in typhoon_download_firmware()
1346 image_data = typhoon_fw->data; in typhoon_download_firmware()
1353 err = -ENOMEM; in typhoon_download_firmware()
1354 dpage = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &dpage_dma, GFP_ATOMIC); in typhoon_download_firmware()
1356 netdev_err(tp->dev, "no DMA mem for firmware\n"); in typhoon_download_firmware()
1367 err = -ETIMEDOUT; in typhoon_download_firmware()
1369 netdev_err(tp->dev, "card ready timeout\n"); in typhoon_download_firmware()
1373 numSections = le32_to_cpu(fHdr->numSections); in typhoon_download_firmware()
1374 load_addr = le32_to_cpu(fHdr->startAddr); in typhoon_download_firmware()
1378 hmac = le32_to_cpu(fHdr->hmacDigest[0]); in typhoon_download_firmware()
1380 hmac = le32_to_cpu(fHdr->hmacDigest[1]); in typhoon_download_firmware()
1382 hmac = le32_to_cpu(fHdr->hmacDigest[2]); in typhoon_download_firmware()
1384 hmac = le32_to_cpu(fHdr->hmacDigest[3]); in typhoon_download_firmware()
1386 hmac = le32_to_cpu(fHdr->hmacDigest[4]); in typhoon_download_firmware()
1400 load_addr = le32_to_cpu(sHdr->startAddr); in typhoon_download_firmware()
1401 section_len = le32_to_cpu(sHdr->len); in typhoon_download_firmware()
1409 netdev_err(tp->dev, "segment ready timeout\n"); in typhoon_download_firmware()
1413 /* Do an pseudo IPv4 checksum on the data -- first in typhoon_download_firmware()
1434 section_len -= len; in typhoon_download_firmware()
1441 netdev_err(tp->dev, "final segment ready timeout\n"); in typhoon_download_firmware()
1448 netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n", in typhoon_download_firmware()
1459 dma_free_coherent(&pdev->dev, PAGE_SIZE, dpage, dpage_dma); in typhoon_download_firmware()
1468 void __iomem *ioaddr = tp->ioaddr; in typhoon_boot_3XP()
1471 netdev_err(tp->dev, "boot ready timeout\n"); in typhoon_boot_3XP()
1476 iowrite32(tp->shared_dma, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_LO); in typhoon_boot_3XP()
1482 netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n", in typhoon_boot_3XP()
1498 return -ETIMEDOUT; in typhoon_boot_3XP()
1505 u32 lastRead = txRing->lastRead; in typhoon_clean_tx()
1512 tx = (struct tx_desc *) (txRing->ringBase + lastRead); in typhoon_clean_tx()
1513 type = tx->flags & TYPHOON_TYPE_MASK; in typhoon_clean_tx()
1518 unsigned long ptr = tx->tx_addr; in typhoon_clean_tx()
1524 skb_dma = (dma_addr_t) le32_to_cpu(tx->frag.addr); in typhoon_clean_tx()
1525 dma_len = le16_to_cpu(tx->len); in typhoon_clean_tx()
1526 dma_unmap_single(&tp->pdev->dev, skb_dma, dma_len, in typhoon_clean_tx()
1530 tx->flags = 0; in typhoon_clean_tx()
1546 if (netif_queue_stopped(tp->dev) && typhoon_num_free(txRing->lastWrite, in typhoon_tx_complete()
1548 netif_wake_queue(tp->dev); in typhoon_tx_complete()
1550 txRing->lastRead = lastRead; in typhoon_tx_complete()
1557 struct typhoon_indexes *indexes = tp->indexes; in typhoon_recycle_rx_skb()
1558 struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; in typhoon_recycle_rx_skb()
1559 struct basic_ring *ring = &tp->rxBuffRing; in typhoon_recycle_rx_skb()
1562 if ((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == in typhoon_recycle_rx_skb()
1563 le32_to_cpu(indexes->rxBuffCleared)) { in typhoon_recycle_rx_skb()
1566 dev_kfree_skb_any(rxb->skb); in typhoon_recycle_rx_skb()
1567 rxb->skb = NULL; in typhoon_recycle_rx_skb()
1571 r = (struct rx_free *) (ring->ringBase + ring->lastWrite); in typhoon_recycle_rx_skb()
1572 typhoon_inc_rxfree_index(&ring->lastWrite, 1); in typhoon_recycle_rx_skb()
1573 r->virtAddr = idx; in typhoon_recycle_rx_skb()
1574 r->physAddr = cpu_to_le32(rxb->dma_addr); in typhoon_recycle_rx_skb()
1578 indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); in typhoon_recycle_rx_skb()
1584 struct typhoon_indexes *indexes = tp->indexes; in typhoon_alloc_rx_skb()
1585 struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; in typhoon_alloc_rx_skb()
1586 struct basic_ring *ring = &tp->rxBuffRing; in typhoon_alloc_rx_skb()
1591 rxb->skb = NULL; in typhoon_alloc_rx_skb()
1593 if ((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == in typhoon_alloc_rx_skb()
1594 le32_to_cpu(indexes->rxBuffCleared)) in typhoon_alloc_rx_skb()
1595 return -ENOMEM; in typhoon_alloc_rx_skb()
1597 skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ); in typhoon_alloc_rx_skb()
1599 return -ENOMEM; in typhoon_alloc_rx_skb()
1608 dma_addr = dma_map_single(&tp->pdev->dev, skb->data, PKT_BUF_SZ, in typhoon_alloc_rx_skb()
1614 r = (struct rx_free *) (ring->ringBase + ring->lastWrite); in typhoon_alloc_rx_skb()
1615 typhoon_inc_rxfree_index(&ring->lastWrite, 1); in typhoon_alloc_rx_skb()
1616 r->virtAddr = idx; in typhoon_alloc_rx_skb()
1617 r->physAddr = cpu_to_le32(dma_addr); in typhoon_alloc_rx_skb()
1618 rxb->skb = skb; in typhoon_alloc_rx_skb()
1619 rxb->dma_addr = dma_addr; in typhoon_alloc_rx_skb()
1623 indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); in typhoon_alloc_rx_skb()
1646 rx = (struct rx_desc *) (rxRing->ringBase + rxaddr); in typhoon_rx()
1647 idx = rx->addr; in typhoon_rx()
1648 rxb = &tp->rxbuffers[idx]; in typhoon_rx()
1649 skb = rxb->skb; in typhoon_rx()
1650 dma_addr = rxb->dma_addr; in typhoon_rx()
1654 if (rx->flags & TYPHOON_RX_ERROR) { in typhoon_rx()
1659 pkt_len = le16_to_cpu(rx->frameLen); in typhoon_rx()
1662 (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) { in typhoon_rx()
1664 dma_sync_single_for_cpu(&tp->pdev->dev, dma_addr, in typhoon_rx()
1666 skb_copy_to_linear_data(new_skb, skb->data, pkt_len); in typhoon_rx()
1667 dma_sync_single_for_device(&tp->pdev->dev, dma_addr, in typhoon_rx()
1675 dma_unmap_single(&tp->pdev->dev, dma_addr, PKT_BUF_SZ, in typhoon_rx()
1679 new_skb->protocol = eth_type_trans(new_skb, tp->dev); in typhoon_rx()
1680 csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD | in typhoon_rx()
1686 new_skb->ip_summed = CHECKSUM_UNNECESSARY; in typhoon_rx()
1690 if (rx->rxStatus & TYPHOON_RX_VLAN) in typhoon_rx()
1692 ntohl(rx->vlanTag) & 0xffff); in typhoon_rx()
1696 budget--; in typhoon_rx()
1709 struct rxbuff_ent *rxb = &tp->rxbuffers[i]; in typhoon_fill_free_ring()
1710 if (rxb->skb) in typhoon_fill_free_ring()
1721 struct typhoon_indexes *indexes = tp->indexes; in typhoon_poll()
1725 if (!tp->awaiting_resp && indexes->respReady != indexes->respCleared) in typhoon_poll()
1728 if (le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead) in typhoon_poll()
1729 typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared); in typhoon_poll()
1733 if (indexes->rxHiCleared != indexes->rxHiReady) { in typhoon_poll()
1734 work_done += typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady, in typhoon_poll()
1735 &indexes->rxHiCleared, budget); in typhoon_poll()
1738 if (indexes->rxLoCleared != indexes->rxLoReady) { in typhoon_poll()
1739 work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady, in typhoon_poll()
1740 &indexes->rxLoCleared, budget - work_done); in typhoon_poll()
1743 if (le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) { in typhoon_poll()
1751 tp->ioaddr + TYPHOON_REG_INTR_MASK); in typhoon_poll()
1752 typhoon_post_pci_writes(tp->ioaddr); in typhoon_poll()
1763 void __iomem *ioaddr = tp->ioaddr; in typhoon_interrupt()
1772 if (napi_schedule_prep(&tp->napi)) { in typhoon_interrupt()
1775 __napi_schedule(&tp->napi); in typhoon_interrupt()
1788 struct rxbuff_ent *rxb = &tp->rxbuffers[i]; in typhoon_free_rx_rings()
1789 if (rxb->skb) { in typhoon_free_rx_rings()
1790 dma_unmap_single(&tp->pdev->dev, rxb->dma_addr, in typhoon_free_rx_rings()
1792 dev_kfree_skb(rxb->skb); in typhoon_free_rx_rings()
1793 rxb->skb = NULL; in typhoon_free_rx_rings()
1801 void __iomem *ioaddr = tp->ioaddr; in typhoon_sleep_early()
1809 netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n", in typhoon_sleep_early()
1817 netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err); in typhoon_sleep_early()
1822 return -ETIMEDOUT; in typhoon_sleep_early()
1827 netif_carrier_off(tp->dev); in typhoon_sleep_early()
1842 pci_enable_wake(tp->pdev, state, 1); in typhoon_sleep()
1843 pci_disable_device(tp->pdev); in typhoon_sleep()
1844 return pci_set_power_state(tp->pdev, state); in typhoon_sleep()
1850 void __iomem *ioaddr = tp->ioaddr; in typhoon_wakeup()
1858 (tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET)) in typhoon_wakeup()
1867 struct net_device *dev = tp->dev; in typhoon_start_runtime()
1868 void __iomem *ioaddr = tp->ioaddr; in typhoon_start_runtime()
1877 netdev_err(tp->dev, "cannot load runtime on 3XP\n"); in typhoon_start_runtime()
1882 netdev_err(tp->dev, "cannot boot 3XP\n"); in typhoon_start_runtime()
1883 err = -EIO; in typhoon_start_runtime()
1894 xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); in typhoon_start_runtime()
1895 xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); in typhoon_start_runtime()
1900 /* Disable IRQ coalescing -- we can reenable it when 3Com gives in typhoon_start_runtime()
1910 xp_cmd.parm1 = tp->xcvr_select; in typhoon_start_runtime()
1922 xp_cmd.parm2 = tp->offload; in typhoon_start_runtime()
1923 xp_cmd.parm3 = tp->offload; in typhoon_start_runtime()
1940 tp->card_state = Running; in typhoon_start_runtime()
1959 struct typhoon_indexes *indexes = tp->indexes; in typhoon_stop_runtime()
1960 struct transmit_ring *txLo = &tp->txLoRing; in typhoon_stop_runtime()
1961 void __iomem *ioaddr = tp->ioaddr; in typhoon_stop_runtime()
1978 if (indexes->txLoCleared == cpu_to_le32(txLo->lastWrite)) in typhoon_stop_runtime()
1984 netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n"); in typhoon_stop_runtime()
1992 tp->card_state = Sleeping; in typhoon_stop_runtime()
1995 memcpy(&tp->stats_saved, &tp->dev->stats, sizeof(struct net_device_stats)); in typhoon_stop_runtime()
2001 netdev_err(tp->dev, "timed out waiting for 3XP to halt\n"); in typhoon_stop_runtime()
2004 netdev_err(tp->dev, "unable to reset 3XP\n"); in typhoon_stop_runtime()
2005 return -ETIMEDOUT; in typhoon_stop_runtime()
2009 if (indexes->txLoCleared != cpu_to_le32(txLo->lastWrite)) { in typhoon_stop_runtime()
2010 indexes->txLoCleared = cpu_to_le32(txLo->lastWrite); in typhoon_stop_runtime()
2011 typhoon_clean_tx(tp, &tp->txLoRing, &indexes->txLoCleared); in typhoon_stop_runtime()
2022 if (typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) { in typhoon_tx_timeout()
2028 typhoon_clean_tx(tp, &tp->txLoRing, &tp->indexes->txLoCleared); in typhoon_tx_timeout()
2041 typhoon_reset(tp->ioaddr, NoWait); in typhoon_tx_timeout()
2055 pci_set_power_state(tp->pdev, PCI_D0); in typhoon_open()
2056 pci_restore_state(tp->pdev); in typhoon_open()
2064 err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED, in typhoon_open()
2065 dev->name, dev); in typhoon_open()
2069 napi_enable(&tp->napi); in typhoon_open()
2073 napi_disable(&tp->napi); in typhoon_open()
2081 free_irq(dev->irq, dev); in typhoon_open()
2086 typhoon_reset(tp->ioaddr, NoWait); in typhoon_open()
2103 napi_disable(&tp->napi); in typhoon_close()
2109 free_irq(dev->irq, dev); in typhoon_close()
2148 typhoon_reset(tp->ioaddr, NoWait); in typhoon_resume()
2149 return -EBUSY; in typhoon_resume()
2166 if (tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) in typhoon_suspend()
2185 xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); in typhoon_suspend()
2186 xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); in typhoon_suspend()
2199 if (typhoon_sleep_early(tp, tp->wol_events) < 0) { in typhoon_suspend()
2210 return -EBUSY; in typhoon_suspend()
2233 * The 50usec delay is arbitrary -- it could probably be smaller. in typhoon_test_mmio()
2267 if (skb_shinfo(skb)->nr_frags > 32 && skb_is_gso(skb)) in typhoon_features_check()
2294 int card_id = (int) ent->driver_data; in typhoon_init_one()
2307 err = -ENOMEM; in typhoon_init_one()
2310 SET_NETDEV_DEV(dev, &pdev->dev); in typhoon_init_one()
2324 err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); in typhoon_init_one()
2334 err = -ENODEV; in typhoon_init_one()
2339 err = -ENODEV; in typhoon_init_one()
2344 err = -ENODEV; in typhoon_init_one()
2349 err = -ENODEV; in typhoon_init_one()
2367 err = -EIO; in typhoon_init_one()
2373 shared = dma_alloc_coherent(&pdev->dev, sizeof(struct typhoon_shared), in typhoon_init_one()
2377 err = -ENOMEM; in typhoon_init_one()
2381 dev->irq = pdev->irq; in typhoon_init_one()
2383 tp->shared = shared; in typhoon_init_one()
2384 tp->shared_dma = shared_dma; in typhoon_init_one()
2385 tp->pdev = pdev; in typhoon_init_one()
2386 tp->tx_pdev = pdev; in typhoon_init_one()
2387 tp->ioaddr = ioaddr; in typhoon_init_one()
2388 tp->tx_ioaddr = ioaddr; in typhoon_init_one()
2389 tp->dev = dev; in typhoon_init_one()
2431 if (!is_valid_ether_addr(dev->dev_addr)) { in typhoon_init_one()
2433 err = -EIO; in typhoon_init_one()
2447 tp->capabilities = typhoon_card_info[card_id].capabilities; in typhoon_init_one()
2448 tp->xcvr_select = TYPHOON_XCVR_AUTONEG; in typhoon_init_one()
2457 tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET; in typhoon_init_one()
2465 /* The chip-specific entries in the device structure. */ in typhoon_init_one()
2466 dev->netdev_ops = &typhoon_netdev_ops; in typhoon_init_one()
2467 netif_napi_add_weight(dev, &tp->napi, typhoon_poll, 16); in typhoon_init_one()
2468 dev->watchdog_timeo = TX_TIMEOUT; in typhoon_init_one()
2470 dev->ethtool_ops = &typhoon_ethtool_ops; in typhoon_init_one()
2476 * on the current 3XP firmware -- it does not respect the offload in typhoon_init_one()
2477 * settings -- so we only allow the user to toggle the TX processing. in typhoon_init_one()
2479 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | in typhoon_init_one()
2481 dev->features = dev->hw_features | in typhoon_init_one()
2496 dev->dev_addr); in typhoon_init_one()
2528 dma_free_coherent(&pdev->dev, sizeof(struct typhoon_shared), shared, in typhoon_init_one()
2554 typhoon_reset(tp->ioaddr, NoWait); in typhoon_remove_one()
2555 pci_iounmap(pdev, tp->ioaddr); in typhoon_remove_one()
2556 dma_free_coherent(&pdev->dev, sizeof(struct typhoon_shared), in typhoon_remove_one()
2557 tp->shared, tp->shared_dma); in typhoon_remove_one()