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>
171 { "3Com Typhoon (3C990-TX)",
173 { "3Com Typhoon (3CR990-TX-95)",
175 { "3Com Typhoon (3CR990-TX-97)",
183 { "3Com Typhoon2 (3C990B-TX-M)",
187 { "3Com Typhoon (3CR990-FX-95)",
189 { "3Com Typhoon (3CR990-FX-97)",
191 { "3Com Typhoon (3CR990-FX-95 Server)",
193 { "3Com Typhoon (3CR990-FX-97 Server)",
195 { "3Com Typhoon2 (3C990B-FX-97)",
200 * bits 0-1 indicate crypto capabilities: (0) variable, (1) DES, or (2) 3DES
203 * bits 12-16 indicate card type: (0) client and (1) server
323 #define skb_tso_size(x) (skb_shinfo(x)->gso_size)
336 /* Increment a ring index -- we can use this for all rings execept in typhoon_inc_index()
408 err = -ETIMEDOUT; in typhoon_reset()
422 * which should be enough (I've see it work well at 100us, but still in typhoon_reset()
443 err = -ETIMEDOUT; in typhoon_wait_status()
452 if (resp->parm1 & TYPHOON_MEDIA_STAT_NO_LINK) in typhoon_media_status()
461 struct basic_ring *ring = &tp->cmdRing; in typhoon_hello()
468 if (spin_trylock(&tp->command_lock)) { in typhoon_hello()
469 cmd = (struct cmd_desc *)(ring->ringBase + ring->lastWrite); in typhoon_hello()
470 typhoon_inc_cmd_index(&ring->lastWrite, 1); in typhoon_hello()
474 iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); in typhoon_hello()
475 spin_unlock(&tp->command_lock); in typhoon_hello()
483 struct typhoon_indexes *indexes = tp->indexes; in typhoon_process_response()
485 u8 *base = tp->respRing.ringBase; in typhoon_process_response() local
490 cleared = le32_to_cpu(indexes->respCleared); in typhoon_process_response()
491 ready = le32_to_cpu(indexes->respReady); in typhoon_process_response()
493 resp = (struct resp_desc *)(base + cleared); in typhoon_process_response()
494 count = resp->numDesc + 1; in typhoon_process_response()
495 if (resp_save && resp->seqNo) { in typhoon_process_response()
497 resp_save->flags = TYPHOON_RESP_ERROR; in typhoon_process_response()
504 wrap_len = cleared + len - RESPONSE_RING_SIZE; in typhoon_process_response()
505 len = RESPONSE_RING_SIZE - cleared; in typhoon_process_response()
511 memcpy(resp_save, base, wrap_len); in typhoon_process_response()
515 } else if (resp->cmd == TYPHOON_CMD_READ_MEDIA_STATUS) { in typhoon_process_response()
516 typhoon_media_status(tp->dev, resp); in typhoon_process_response()
517 } else if (resp->cmd == TYPHOON_CMD_HELLO_RESP) { in typhoon_process_response()
520 netdev_err(tp->dev, in typhoon_process_response()
522 le16_to_cpu(resp->cmd), in typhoon_process_response()
523 resp->numDesc, resp->flags, in typhoon_process_response()
524 le16_to_cpu(resp->parm1), in typhoon_process_response()
525 le32_to_cpu(resp->parm2), in typhoon_process_response()
526 le32_to_cpu(resp->parm3)); in typhoon_process_response()
533 indexes->respCleared = cpu_to_le32(cleared); in typhoon_process_response()
542 * different size than the cmd_desc -- everyone else is the same in typhoon_num_free()
546 return (ringSize + lastRead - lastWrite - 1) % ringSize; in typhoon_num_free()
552 int lastWrite = tp->cmdRing.lastWrite; in typhoon_num_free_cmd()
553 int cmdCleared = le32_to_cpu(tp->indexes->cmdCleared); in typhoon_num_free_cmd()
561 int respReady = le32_to_cpu(tp->indexes->respReady); in typhoon_num_free_resp()
562 int respCleared = le32_to_cpu(tp->indexes->respCleared); in typhoon_num_free_resp()
571 return typhoon_num_free(ring->lastWrite, ring->lastRead, TXLO_ENTRIES); in typhoon_num_free_tx()
578 struct typhoon_indexes *indexes = tp->indexes; in typhoon_issue_command()
579 struct basic_ring *ring = &tp->cmdRing; in typhoon_issue_command()
586 spin_lock(&tp->command_lock); in typhoon_issue_command()
592 netdev_err(tp->dev, "no descs for cmd, had (needed) %d (%d) cmd, %d (%d) resp\n", in typhoon_issue_command()
594 err = -ENOMEM; in typhoon_issue_command()
598 if (cmd->flags & TYPHOON_CMD_RESPOND) { in typhoon_issue_command()
602 tp->awaiting_resp = 1; in typhoon_issue_command()
611 if (unlikely(ring->lastWrite + len > COMMAND_RING_SIZE)) { in typhoon_issue_command()
612 wrap_len = ring->lastWrite + len - COMMAND_RING_SIZE; in typhoon_issue_command()
613 len = COMMAND_RING_SIZE - ring->lastWrite; in typhoon_issue_command()
616 memcpy(ring->ringBase + ring->lastWrite, cmd, len); in typhoon_issue_command()
620 memcpy(ring->ringBase, wrap_ptr, wrap_len); in typhoon_issue_command()
623 typhoon_inc_cmd_index(&ring->lastWrite, num_cmd); in typhoon_issue_command()
628 iowrite32(ring->lastWrite, tp->ioaddr + TYPHOON_REG_CMD_READY); in typhoon_issue_command()
629 typhoon_post_pci_writes(tp->ioaddr); in typhoon_issue_command()
631 if ((cmd->flags & TYPHOON_CMD_RESPOND) == 0) in typhoon_issue_command()
640 * 3Com has implemented irq coalescing, we would likely timeout -- in typhoon_issue_command()
652 if (indexes->respCleared != indexes->respReady) in typhoon_issue_command()
659 err = -ETIMEDOUT; in typhoon_issue_command()
666 if (resp->flags & TYPHOON_RESP_ERROR) in typhoon_issue_command()
667 err = -EIO; in typhoon_issue_command()
670 if (tp->awaiting_resp) { in typhoon_issue_command()
671 tp->awaiting_resp = 0; in typhoon_issue_command()
676 * of tp->awaiting_resp, we could have missed the interrupt in typhoon_issue_command()
681 if (indexes->respCleared != indexes->respReady) in typhoon_issue_command()
682 iowrite32(1, tp->ioaddr + TYPHOON_REG_SELF_INTERRUPT); in typhoon_issue_command()
685 spin_unlock(&tp->command_lock); in typhoon_issue_command()
696 tcpd = (struct tcpopt_desc *) (txRing->ringBase + txRing->lastWrite); in typhoon_tso_fill()
697 tcpd_offset += txRing->lastWrite; in typhoon_tso_fill()
699 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_tso_fill()
701 tcpd->flags = TYPHOON_OPT_DESC | TYPHOON_OPT_TCP_SEG; in typhoon_tso_fill()
702 tcpd->numDesc = 1; in typhoon_tso_fill()
703 tcpd->mss_flags = cpu_to_le16(skb_tso_size(skb)); in typhoon_tso_fill()
704 tcpd->mss_flags |= TYPHOON_TSO_FIRST | TYPHOON_TSO_LAST; in typhoon_tso_fill()
705 tcpd->respAddrLo = cpu_to_le32(tcpd_offset); in typhoon_tso_fill()
706 tcpd->bytesTx = cpu_to_le32(skb->len); in typhoon_tso_fill()
707 tcpd->status = 0; in typhoon_tso_fill()
725 txRing = &tp->txLoRing; in typhoon_start_tx()
728 * one for the ->data area of it. in typhoon_start_tx()
738 numDesc = skb_shinfo(skb)->nr_frags + 1; in typhoon_start_tx()
754 first_txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); in typhoon_start_tx()
755 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_start_tx()
757 first_txd->flags = TYPHOON_TX_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
758 first_txd->numDesc = 0; in typhoon_start_tx()
759 first_txd->len = 0; in typhoon_start_tx()
760 first_txd->tx_addr = (u64)((unsigned long) skb); in typhoon_start_tx()
761 first_txd->processFlags = 0; in typhoon_start_tx()
763 if (skb->ip_summed == CHECKSUM_PARTIAL) { in typhoon_start_tx()
765 first_txd->processFlags |= TYPHOON_TX_PF_TCP_CHKSUM; in typhoon_start_tx()
766 first_txd->processFlags |= TYPHOON_TX_PF_UDP_CHKSUM; in typhoon_start_tx()
767 first_txd->processFlags |= TYPHOON_TX_PF_IP_CHKSUM; in typhoon_start_tx()
771 first_txd->processFlags |= in typhoon_start_tx()
773 first_txd->processFlags |= in typhoon_start_tx()
779 first_txd->processFlags |= TYPHOON_TX_PF_TCP_SEGMENT; in typhoon_start_tx()
780 first_txd->numDesc++; in typhoon_start_tx()
782 typhoon_tso_fill(skb, txRing, tp->txlo_dma_addr); in typhoon_start_tx()
785 txd = (struct tx_desc *) (txRing->ringBase + txRing->lastWrite); in typhoon_start_tx()
786 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_start_tx()
788 /* No need to worry about padding packet -- the firmware pads in typhoon_start_tx()
791 if (skb_shinfo(skb)->nr_frags == 0) { in typhoon_start_tx()
792 skb_dma = dma_map_single(&tp->tx_pdev->dev, skb->data, in typhoon_start_tx()
793 skb->len, DMA_TO_DEVICE); in typhoon_start_tx()
794 txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
795 txd->len = cpu_to_le16(skb->len); in typhoon_start_tx()
796 txd->frag.addr = cpu_to_le32(skb_dma); in typhoon_start_tx()
797 txd->frag.addrHi = 0; in typhoon_start_tx()
798 first_txd->numDesc++; in typhoon_start_tx()
803 skb_dma = dma_map_single(&tp->tx_pdev->dev, skb->data, len, in typhoon_start_tx()
805 txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
806 txd->len = cpu_to_le16(len); in typhoon_start_tx()
807 txd->frag.addr = cpu_to_le32(skb_dma); in typhoon_start_tx()
808 txd->frag.addrHi = 0; in typhoon_start_tx()
809 first_txd->numDesc++; in typhoon_start_tx()
811 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { in typhoon_start_tx()
812 const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; in typhoon_start_tx()
815 txd = (struct tx_desc *) (txRing->ringBase + in typhoon_start_tx()
816 txRing->lastWrite); in typhoon_start_tx()
817 typhoon_inc_tx_index(&txRing->lastWrite, 1); in typhoon_start_tx()
821 skb_dma = dma_map_single(&tp->tx_pdev->dev, frag_addr, in typhoon_start_tx()
823 txd->flags = TYPHOON_FRAG_DESC | TYPHOON_DESC_VALID; in typhoon_start_tx()
824 txd->len = cpu_to_le16(len); in typhoon_start_tx()
825 txd->frag.addr = cpu_to_le32(skb_dma); in typhoon_start_tx()
826 txd->frag.addrHi = 0; in typhoon_start_tx()
827 first_txd->numDesc++; in typhoon_start_tx()
834 iowrite32(txRing->lastWrite, tp->tx_ioaddr + txRing->writeRegister); in typhoon_start_tx()
838 * descriptors -- one to prevent ring wrap, and one for the in typhoon_start_tx()
866 if (dev->flags & IFF_PROMISC) { in typhoon_set_rx_mode()
869 (dev->flags & IFF_ALLMULTI)) { in typhoon_set_rx_mode()
877 int bit = ether_crc(ETH_ALEN, ha->addr) & 0x3f; in typhoon_set_rx_mode()
899 struct net_device_stats *stats = &tp->dev->stats; in typhoon_do_get_stats()
900 struct net_device_stats *saved = &tp->stats_saved; in typhoon_do_get_stats()
915 * ethtool_ops->get_{strings,stats}() in typhoon_do_get_stats()
917 stats->tx_packets = le32_to_cpu(s->txPackets) + in typhoon_do_get_stats()
918 saved->tx_packets; in typhoon_do_get_stats()
919 stats->tx_bytes = le64_to_cpu(s->txBytes) + in typhoon_do_get_stats()
920 saved->tx_bytes; in typhoon_do_get_stats()
921 stats->tx_errors = le32_to_cpu(s->txCarrierLost) + in typhoon_do_get_stats()
922 saved->tx_errors; in typhoon_do_get_stats()
923 stats->tx_carrier_errors = le32_to_cpu(s->txCarrierLost) + in typhoon_do_get_stats()
924 saved->tx_carrier_errors; in typhoon_do_get_stats()
925 stats->collisions = le32_to_cpu(s->txMultipleCollisions) + in typhoon_do_get_stats()
926 saved->collisions; in typhoon_do_get_stats()
927 stats->rx_packets = le32_to_cpu(s->rxPacketsGood) + in typhoon_do_get_stats()
928 saved->rx_packets; in typhoon_do_get_stats()
929 stats->rx_bytes = le64_to_cpu(s->rxBytesGood) + in typhoon_do_get_stats()
930 saved->rx_bytes; in typhoon_do_get_stats()
931 stats->rx_fifo_errors = le32_to_cpu(s->rxFifoOverruns) + in typhoon_do_get_stats()
932 saved->rx_fifo_errors; in typhoon_do_get_stats()
933 stats->rx_errors = le32_to_cpu(s->rxFifoOverruns) + in typhoon_do_get_stats()
934 le32_to_cpu(s->BadSSD) + le32_to_cpu(s->rxCrcErrors) + in typhoon_do_get_stats()
935 saved->rx_errors; in typhoon_do_get_stats()
936 stats->rx_crc_errors = le32_to_cpu(s->rxCrcErrors) + in typhoon_do_get_stats()
937 saved->rx_crc_errors; in typhoon_do_get_stats()
938 stats->rx_length_errors = le32_to_cpu(s->rxOversized) + in typhoon_do_get_stats()
939 saved->rx_length_errors; in typhoon_do_get_stats()
940 tp->speed = (s->linkStatus & TYPHOON_LINK_100MBPS) ? in typhoon_do_get_stats()
942 tp->duplex = (s->linkStatus & TYPHOON_LINK_FULL_DUPLEX) ? in typhoon_do_get_stats()
952 struct net_device_stats *stats = &tp->dev->stats; in typhoon_get_stats()
953 struct net_device_stats *saved = &tp->stats_saved; in typhoon_get_stats()
956 if (tp->card_state == Sleeping) in typhoon_get_stats()
971 struct pci_dev *pci_dev = tp->pdev; in typhoon_get_drvinfo()
976 if (tp->card_state == Sleeping) { in typhoon_get_drvinfo()
977 strlcpy(info->fw_version, "Sleep image", in typhoon_get_drvinfo()
978 sizeof(info->fw_version)); in typhoon_get_drvinfo()
982 strlcpy(info->fw_version, "Unknown runtime", in typhoon_get_drvinfo()
983 sizeof(info->fw_version)); in typhoon_get_drvinfo()
986 snprintf(info->fw_version, sizeof(info->fw_version), in typhoon_get_drvinfo()
992 strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); in typhoon_get_drvinfo()
993 strlcpy(info->bus_info, pci_name(pci_dev), sizeof(info->bus_info)); in typhoon_get_drvinfo()
1006 switch (tp->xcvr_select) { in typhoon_get_link_ksettings()
1028 if (tp->capabilities & TYPHOON_FIBER) { in typhoon_get_link_ksettings()
1031 cmd->base.port = PORT_FIBRE; in typhoon_get_link_ksettings()
1037 cmd->base.port = PORT_TP; in typhoon_get_link_ksettings()
1042 cmd->base.speed = tp->speed; in typhoon_get_link_ksettings()
1043 cmd->base.duplex = tp->duplex; in typhoon_get_link_ksettings()
1044 cmd->base.phy_address = 0; in typhoon_get_link_ksettings()
1045 if (tp->xcvr_select == TYPHOON_XCVR_AUTONEG) in typhoon_get_link_ksettings()
1046 cmd->base.autoneg = AUTONEG_ENABLE; in typhoon_get_link_ksettings()
1048 cmd->base.autoneg = AUTONEG_DISABLE; in typhoon_get_link_ksettings()
1050 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, in typhoon_get_link_ksettings()
1052 ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, in typhoon_get_link_ksettings()
1063 u32 speed = cmd->base.speed; in typhoon_set_link_ksettings()
1068 err = -EINVAL; in typhoon_set_link_ksettings()
1069 if (cmd->base.autoneg == AUTONEG_ENABLE) { in typhoon_set_link_ksettings()
1072 if (cmd->base.duplex == DUPLEX_HALF) { in typhoon_set_link_ksettings()
1079 } else if (cmd->base.duplex == DUPLEX_FULL) { in typhoon_set_link_ksettings()
1096 tp->xcvr_select = xcvr; in typhoon_set_link_ksettings()
1097 if (cmd->base.autoneg == AUTONEG_ENABLE) { in typhoon_set_link_ksettings()
1098 tp->speed = 0xff; /* invalid */ in typhoon_set_link_ksettings()
1099 tp->duplex = 0xff; /* invalid */ in typhoon_set_link_ksettings()
1101 tp->speed = speed; in typhoon_set_link_ksettings()
1102 tp->duplex = cmd->base.duplex; in typhoon_set_link_ksettings()
1114 wol->supported = WAKE_PHY | WAKE_MAGIC; in typhoon_get_wol()
1115 wol->wolopts = 0; in typhoon_get_wol()
1116 if (tp->wol_events & TYPHOON_WAKE_LINK_EVENT) in typhoon_get_wol()
1117 wol->wolopts |= WAKE_PHY; in typhoon_get_wol()
1118 if (tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) in typhoon_get_wol()
1119 wol->wolopts |= WAKE_MAGIC; in typhoon_get_wol()
1120 memset(&wol->sopass, 0, sizeof(wol->sopass)); in typhoon_get_wol()
1128 if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC)) in typhoon_set_wol()
1129 return -EINVAL; in typhoon_set_wol()
1131 tp->wol_events = 0; in typhoon_set_wol()
1132 if (wol->wolopts & WAKE_PHY) in typhoon_set_wol()
1133 tp->wol_events |= TYPHOON_WAKE_LINK_EVENT; in typhoon_set_wol()
1134 if (wol->wolopts & WAKE_MAGIC) in typhoon_set_wol()
1135 tp->wol_events |= TYPHOON_WAKE_MAGIC_PKT; in typhoon_set_wol()
1143 ering->rx_max_pending = RXENT_ENTRIES; in typhoon_get_ringparam()
1144 ering->tx_max_pending = TXLO_ENTRIES - 1; in typhoon_get_ringparam()
1146 ering->rx_pending = RXENT_ENTRIES; in typhoon_get_ringparam()
1147 ering->tx_pending = TXLO_ENTRIES - 1; in typhoon_get_ringparam()
1172 err = -ETIMEDOUT; in typhoon_wait_interrupt()
1184 struct typhoon_interface *iface = &tp->shared->iface; in typhoon_init_interface()
1187 memset(tp->shared, 0, sizeof(struct typhoon_shared)); in typhoon_init_interface()
1191 shared_dma = tp->shared_dma + shared_offset(indexes); in typhoon_init_interface()
1192 iface->ringIndex = cpu_to_le32(shared_dma); in typhoon_init_interface()
1194 shared_dma = tp->shared_dma + shared_offset(txLo); in typhoon_init_interface()
1195 iface->txLoAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1196 iface->txLoSize = cpu_to_le32(TXLO_ENTRIES * sizeof(struct tx_desc)); in typhoon_init_interface()
1198 shared_dma = tp->shared_dma + shared_offset(txHi); in typhoon_init_interface()
1199 iface->txHiAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1200 iface->txHiSize = cpu_to_le32(TXHI_ENTRIES * sizeof(struct tx_desc)); in typhoon_init_interface()
1202 shared_dma = tp->shared_dma + shared_offset(rxBuff); in typhoon_init_interface()
1203 iface->rxBuffAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1204 iface->rxBuffSize = cpu_to_le32(RXFREE_ENTRIES * in typhoon_init_interface()
1207 shared_dma = tp->shared_dma + shared_offset(rxLo); in typhoon_init_interface()
1208 iface->rxLoAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1209 iface->rxLoSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); in typhoon_init_interface()
1211 shared_dma = tp->shared_dma + shared_offset(rxHi); in typhoon_init_interface()
1212 iface->rxHiAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1213 iface->rxHiSize = cpu_to_le32(RX_ENTRIES * sizeof(struct rx_desc)); in typhoon_init_interface()
1215 shared_dma = tp->shared_dma + shared_offset(cmd); in typhoon_init_interface()
1216 iface->cmdAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1217 iface->cmdSize = cpu_to_le32(COMMAND_RING_SIZE); in typhoon_init_interface()
1219 shared_dma = tp->shared_dma + shared_offset(resp); in typhoon_init_interface()
1220 iface->respAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1221 iface->respSize = cpu_to_le32(RESPONSE_RING_SIZE); in typhoon_init_interface()
1223 shared_dma = tp->shared_dma + shared_offset(zeroWord); in typhoon_init_interface()
1224 iface->zeroAddr = cpu_to_le32(shared_dma); in typhoon_init_interface()
1226 tp->indexes = &tp->shared->indexes; in typhoon_init_interface()
1227 tp->txLoRing.ringBase = (u8 *) tp->shared->txLo; in typhoon_init_interface()
1228 tp->txHiRing.ringBase = (u8 *) tp->shared->txHi; in typhoon_init_interface()
1229 tp->rxLoRing.ringBase = (u8 *) tp->shared->rxLo; in typhoon_init_interface()
1230 tp->rxHiRing.ringBase = (u8 *) tp->shared->rxHi; in typhoon_init_interface()
1231 tp->rxBuffRing.ringBase = (u8 *) tp->shared->rxBuff; in typhoon_init_interface()
1232 tp->cmdRing.ringBase = (u8 *) tp->shared->cmd; in typhoon_init_interface()
1233 tp->respRing.ringBase = (u8 *) tp->shared->resp; in typhoon_init_interface()
1235 tp->txLoRing.writeRegister = TYPHOON_REG_TX_LO_READY; in typhoon_init_interface()
1236 tp->txHiRing.writeRegister = TYPHOON_REG_TX_HI_READY; in typhoon_init_interface()
1238 tp->txlo_dma_addr = le32_to_cpu(iface->txLoAddr); in typhoon_init_interface()
1239 tp->card_state = Sleeping; in typhoon_init_interface()
1241 tp->offload = TYPHOON_OFFLOAD_IP_CHKSUM | TYPHOON_OFFLOAD_TCP_CHKSUM; in typhoon_init_interface()
1242 tp->offload |= TYPHOON_OFFLOAD_UDP_CHKSUM | TSO_OFFLOAD_ON; in typhoon_init_interface()
1243 tp->offload |= TYPHOON_OFFLOAD_VLAN; in typhoon_init_interface()
1245 spin_lock_init(&tp->command_lock); in typhoon_init_interface()
1254 memset(tp->indexes, 0, sizeof(struct typhoon_indexes)); in typhoon_init_rings()
1256 tp->txLoRing.lastWrite = 0; in typhoon_init_rings()
1257 tp->txHiRing.lastWrite = 0; in typhoon_init_rings()
1258 tp->rxLoRing.lastWrite = 0; in typhoon_init_rings()
1259 tp->rxHiRing.lastWrite = 0; in typhoon_init_rings()
1260 tp->rxBuffRing.lastWrite = 0; in typhoon_init_rings()
1261 tp->cmdRing.lastWrite = 0; in typhoon_init_rings()
1262 tp->respRing.lastWrite = 0; in typhoon_init_rings()
1264 tp->txLoRing.lastRead = 0; in typhoon_init_rings()
1265 tp->txHiRing.lastRead = 0; in typhoon_init_rings()
1284 err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); in typhoon_request_firmware()
1286 netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", in typhoon_request_firmware()
1291 image_data = typhoon_fw->data; in typhoon_request_firmware()
1292 remaining = typhoon_fw->size; in typhoon_request_firmware()
1297 if (memcmp(fHdr->tag, "TYPHOON", 8)) in typhoon_request_firmware()
1300 numSections = le32_to_cpu(fHdr->numSections); in typhoon_request_firmware()
1302 remaining -= sizeof(struct typhoon_file_header); in typhoon_request_firmware()
1304 while (numSections--) { in typhoon_request_firmware()
1310 section_len = le32_to_cpu(sHdr->len); in typhoon_request_firmware()
1316 remaining -= section_len; in typhoon_request_firmware()
1322 netdev_err(tp->dev, "Invalid firmware image\n"); in typhoon_request_firmware()
1325 return -EINVAL; in typhoon_request_firmware()
1331 void __iomem *ioaddr = tp->ioaddr; in typhoon_download_firmware()
1332 struct pci_dev *pdev = tp->pdev; in typhoon_download_firmware()
1349 image_data = typhoon_fw->data; in typhoon_download_firmware()
1356 err = -ENOMEM; in typhoon_download_firmware()
1357 dpage = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, &dpage_dma, GFP_ATOMIC); in typhoon_download_firmware()
1359 netdev_err(tp->dev, "no DMA mem for firmware\n"); in typhoon_download_firmware()
1370 err = -ETIMEDOUT; in typhoon_download_firmware()
1372 netdev_err(tp->dev, "card ready timeout\n"); in typhoon_download_firmware()
1376 numSections = le32_to_cpu(fHdr->numSections); in typhoon_download_firmware()
1377 load_addr = le32_to_cpu(fHdr->startAddr); in typhoon_download_firmware()
1381 hmac = le32_to_cpu(fHdr->hmacDigest[0]); in typhoon_download_firmware()
1383 hmac = le32_to_cpu(fHdr->hmacDigest[1]); in typhoon_download_firmware()
1385 hmac = le32_to_cpu(fHdr->hmacDigest[2]); in typhoon_download_firmware()
1387 hmac = le32_to_cpu(fHdr->hmacDigest[3]); in typhoon_download_firmware()
1389 hmac = le32_to_cpu(fHdr->hmacDigest[4]); in typhoon_download_firmware()
1403 load_addr = le32_to_cpu(sHdr->startAddr); in typhoon_download_firmware()
1404 section_len = le32_to_cpu(sHdr->len); in typhoon_download_firmware()
1412 netdev_err(tp->dev, "segment ready timeout\n"); in typhoon_download_firmware()
1416 /* Do an pseudo IPv4 checksum on the data -- first in typhoon_download_firmware()
1437 section_len -= len; in typhoon_download_firmware()
1444 netdev_err(tp->dev, "final segment ready timeout\n"); in typhoon_download_firmware()
1451 netdev_err(tp->dev, "boot ready timeout, status 0x%0x\n", in typhoon_download_firmware()
1462 dma_free_coherent(&pdev->dev, PAGE_SIZE, dpage, dpage_dma); in typhoon_download_firmware()
1471 void __iomem *ioaddr = tp->ioaddr; in typhoon_boot_3XP()
1474 netdev_err(tp->dev, "boot ready timeout\n"); in typhoon_boot_3XP()
1479 iowrite32(tp->shared_dma, ioaddr + TYPHOON_REG_BOOT_RECORD_ADDR_LO); in typhoon_boot_3XP()
1485 netdev_err(tp->dev, "boot finish timeout (status 0x%x)\n", in typhoon_boot_3XP()
1501 return -ETIMEDOUT; in typhoon_boot_3XP()
1508 u32 lastRead = txRing->lastRead; in typhoon_clean_tx()
1515 tx = (struct tx_desc *) (txRing->ringBase + lastRead); in typhoon_clean_tx()
1516 type = tx->flags & TYPHOON_TYPE_MASK; in typhoon_clean_tx()
1521 unsigned long ptr = tx->tx_addr; in typhoon_clean_tx()
1527 skb_dma = (dma_addr_t) le32_to_cpu(tx->frag.addr); in typhoon_clean_tx()
1528 dma_len = le16_to_cpu(tx->len); in typhoon_clean_tx()
1529 dma_unmap_single(&tp->pdev->dev, skb_dma, dma_len, in typhoon_clean_tx()
1533 tx->flags = 0; in typhoon_clean_tx()
1549 if (netif_queue_stopped(tp->dev) && typhoon_num_free(txRing->lastWrite, in typhoon_tx_complete()
1551 netif_wake_queue(tp->dev); in typhoon_tx_complete()
1553 txRing->lastRead = lastRead; in typhoon_tx_complete()
1560 struct typhoon_indexes *indexes = tp->indexes; in typhoon_recycle_rx_skb()
1561 struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; in typhoon_recycle_rx_skb()
1562 struct basic_ring *ring = &tp->rxBuffRing; in typhoon_recycle_rx_skb()
1565 if ((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == in typhoon_recycle_rx_skb()
1566 le32_to_cpu(indexes->rxBuffCleared)) { in typhoon_recycle_rx_skb()
1569 dev_kfree_skb_any(rxb->skb); in typhoon_recycle_rx_skb()
1570 rxb->skb = NULL; in typhoon_recycle_rx_skb()
1574 r = (struct rx_free *) (ring->ringBase + ring->lastWrite); in typhoon_recycle_rx_skb()
1575 typhoon_inc_rxfree_index(&ring->lastWrite, 1); in typhoon_recycle_rx_skb()
1576 r->virtAddr = idx; in typhoon_recycle_rx_skb()
1577 r->physAddr = cpu_to_le32(rxb->dma_addr); in typhoon_recycle_rx_skb()
1581 indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); in typhoon_recycle_rx_skb()
1587 struct typhoon_indexes *indexes = tp->indexes; in typhoon_alloc_rx_skb()
1588 struct rxbuff_ent *rxb = &tp->rxbuffers[idx]; in typhoon_alloc_rx_skb()
1589 struct basic_ring *ring = &tp->rxBuffRing; in typhoon_alloc_rx_skb()
1594 rxb->skb = NULL; in typhoon_alloc_rx_skb()
1596 if ((ring->lastWrite + sizeof(*r)) % (RXFREE_ENTRIES * sizeof(*r)) == in typhoon_alloc_rx_skb()
1597 le32_to_cpu(indexes->rxBuffCleared)) in typhoon_alloc_rx_skb()
1598 return -ENOMEM; in typhoon_alloc_rx_skb()
1600 skb = netdev_alloc_skb(tp->dev, PKT_BUF_SZ); in typhoon_alloc_rx_skb()
1602 return -ENOMEM; in typhoon_alloc_rx_skb()
1611 dma_addr = dma_map_single(&tp->pdev->dev, skb->data, PKT_BUF_SZ, in typhoon_alloc_rx_skb()
1617 r = (struct rx_free *) (ring->ringBase + ring->lastWrite); in typhoon_alloc_rx_skb()
1618 typhoon_inc_rxfree_index(&ring->lastWrite, 1); in typhoon_alloc_rx_skb()
1619 r->virtAddr = idx; in typhoon_alloc_rx_skb()
1620 r->physAddr = cpu_to_le32(dma_addr); in typhoon_alloc_rx_skb()
1621 rxb->skb = skb; in typhoon_alloc_rx_skb()
1622 rxb->dma_addr = dma_addr; in typhoon_alloc_rx_skb()
1626 indexes->rxBuffReady = cpu_to_le32(ring->lastWrite); in typhoon_alloc_rx_skb()
1649 rx = (struct rx_desc *) (rxRing->ringBase + rxaddr); in typhoon_rx()
1650 idx = rx->addr; in typhoon_rx()
1651 rxb = &tp->rxbuffers[idx]; in typhoon_rx()
1652 skb = rxb->skb; in typhoon_rx()
1653 dma_addr = rxb->dma_addr; in typhoon_rx()
1657 if (rx->flags & TYPHOON_RX_ERROR) { in typhoon_rx()
1662 pkt_len = le16_to_cpu(rx->frameLen); in typhoon_rx()
1665 (new_skb = netdev_alloc_skb(tp->dev, pkt_len + 2)) != NULL) { in typhoon_rx()
1667 dma_sync_single_for_cpu(&tp->pdev->dev, dma_addr, in typhoon_rx()
1669 skb_copy_to_linear_data(new_skb, skb->data, pkt_len); in typhoon_rx()
1670 dma_sync_single_for_device(&tp->pdev->dev, dma_addr, in typhoon_rx()
1678 dma_unmap_single(&tp->pdev->dev, dma_addr, PKT_BUF_SZ, in typhoon_rx()
1682 new_skb->protocol = eth_type_trans(new_skb, tp->dev); in typhoon_rx()
1683 csum_bits = rx->rxStatus & (TYPHOON_RX_IP_CHK_GOOD | in typhoon_rx()
1689 new_skb->ip_summed = CHECKSUM_UNNECESSARY; in typhoon_rx()
1693 if (rx->rxStatus & TYPHOON_RX_VLAN) in typhoon_rx()
1695 ntohl(rx->vlanTag) & 0xffff); in typhoon_rx()
1699 budget--; in typhoon_rx()
1712 struct rxbuff_ent *rxb = &tp->rxbuffers[i]; in typhoon_fill_free_ring()
1713 if (rxb->skb) in typhoon_fill_free_ring()
1724 struct typhoon_indexes *indexes = tp->indexes; in typhoon_poll()
1728 if (!tp->awaiting_resp && indexes->respReady != indexes->respCleared) in typhoon_poll()
1731 if (le32_to_cpu(indexes->txLoCleared) != tp->txLoRing.lastRead) in typhoon_poll()
1732 typhoon_tx_complete(tp, &tp->txLoRing, &indexes->txLoCleared); in typhoon_poll()
1736 if (indexes->rxHiCleared != indexes->rxHiReady) { in typhoon_poll()
1737 work_done += typhoon_rx(tp, &tp->rxHiRing, &indexes->rxHiReady, in typhoon_poll()
1738 &indexes->rxHiCleared, budget); in typhoon_poll()
1741 if (indexes->rxLoCleared != indexes->rxLoReady) { in typhoon_poll()
1742 work_done += typhoon_rx(tp, &tp->rxLoRing, &indexes->rxLoReady, in typhoon_poll()
1743 &indexes->rxLoCleared, budget - work_done); in typhoon_poll()
1746 if (le32_to_cpu(indexes->rxBuffCleared) == tp->rxBuffRing.lastWrite) { in typhoon_poll()
1754 tp->ioaddr + TYPHOON_REG_INTR_MASK); in typhoon_poll()
1755 typhoon_post_pci_writes(tp->ioaddr); in typhoon_poll()
1766 void __iomem *ioaddr = tp->ioaddr; in typhoon_interrupt()
1775 if (napi_schedule_prep(&tp->napi)) { in typhoon_interrupt()
1778 __napi_schedule(&tp->napi); in typhoon_interrupt()
1791 struct rxbuff_ent *rxb = &tp->rxbuffers[i]; in typhoon_free_rx_rings()
1792 if (rxb->skb) { in typhoon_free_rx_rings()
1793 dma_unmap_single(&tp->pdev->dev, rxb->dma_addr, in typhoon_free_rx_rings()
1795 dev_kfree_skb(rxb->skb); in typhoon_free_rx_rings()
1796 rxb->skb = NULL; in typhoon_free_rx_rings()
1804 void __iomem *ioaddr = tp->ioaddr; in typhoon_sleep_early()
1812 netdev_err(tp->dev, "typhoon_sleep(): wake events cmd err %d\n", in typhoon_sleep_early()
1820 netdev_err(tp->dev, "typhoon_sleep(): sleep cmd err %d\n", err); in typhoon_sleep_early()
1825 return -ETIMEDOUT; in typhoon_sleep_early()
1830 netif_carrier_off(tp->dev); in typhoon_sleep_early()
1845 pci_enable_wake(tp->pdev, state, 1); in typhoon_sleep()
1846 pci_disable_device(tp->pdev); in typhoon_sleep()
1847 return pci_set_power_state(tp->pdev, state); in typhoon_sleep()
1853 void __iomem *ioaddr = tp->ioaddr; in typhoon_wakeup()
1861 (tp->capabilities & TYPHOON_WAKEUP_NEEDS_RESET)) in typhoon_wakeup()
1870 struct net_device *dev = tp->dev; in typhoon_start_runtime()
1871 void __iomem *ioaddr = tp->ioaddr; in typhoon_start_runtime()
1880 netdev_err(tp->dev, "cannot load runtime on 3XP\n"); in typhoon_start_runtime()
1885 netdev_err(tp->dev, "cannot boot 3XP\n"); in typhoon_start_runtime()
1886 err = -EIO; in typhoon_start_runtime()
1897 xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); in typhoon_start_runtime()
1898 xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); in typhoon_start_runtime()
1903 /* Disable IRQ coalescing -- we can reenable it when 3Com gives in typhoon_start_runtime()
1913 xp_cmd.parm1 = tp->xcvr_select; in typhoon_start_runtime()
1925 xp_cmd.parm2 = tp->offload; in typhoon_start_runtime()
1926 xp_cmd.parm3 = tp->offload; in typhoon_start_runtime()
1943 tp->card_state = Running; in typhoon_start_runtime()
1962 struct typhoon_indexes *indexes = tp->indexes; in typhoon_stop_runtime()
1963 struct transmit_ring *txLo = &tp->txLoRing; in typhoon_stop_runtime()
1964 void __iomem *ioaddr = tp->ioaddr; in typhoon_stop_runtime()
1981 if (indexes->txLoCleared == cpu_to_le32(txLo->lastWrite)) in typhoon_stop_runtime()
1987 netdev_err(tp->dev, "halt timed out waiting for Tx to complete\n"); in typhoon_stop_runtime()
1995 tp->card_state = Sleeping; in typhoon_stop_runtime()
1998 memcpy(&tp->stats_saved, &tp->dev->stats, sizeof(struct net_device_stats)); in typhoon_stop_runtime()
2004 netdev_err(tp->dev, "timed out waiting for 3XP to halt\n"); in typhoon_stop_runtime()
2007 netdev_err(tp->dev, "unable to reset 3XP\n"); in typhoon_stop_runtime()
2008 return -ETIMEDOUT; in typhoon_stop_runtime()
2012 if (indexes->txLoCleared != cpu_to_le32(txLo->lastWrite)) { in typhoon_stop_runtime()
2013 indexes->txLoCleared = cpu_to_le32(txLo->lastWrite); in typhoon_stop_runtime()
2014 typhoon_clean_tx(tp, &tp->txLoRing, &indexes->txLoCleared); in typhoon_stop_runtime()
2025 if (typhoon_reset(tp->ioaddr, WaitNoSleep) < 0) { in typhoon_tx_timeout()
2031 typhoon_clean_tx(tp, &tp->txLoRing, &tp->indexes->txLoCleared); in typhoon_tx_timeout()
2044 typhoon_reset(tp->ioaddr, NoWait); in typhoon_tx_timeout()
2058 pci_set_power_state(tp->pdev, PCI_D0); in typhoon_open()
2059 pci_restore_state(tp->pdev); in typhoon_open()
2067 err = request_irq(dev->irq, typhoon_interrupt, IRQF_SHARED, in typhoon_open()
2068 dev->name, dev); in typhoon_open()
2072 napi_enable(&tp->napi); in typhoon_open()
2076 napi_disable(&tp->napi); in typhoon_open()
2084 free_irq(dev->irq, dev); in typhoon_open()
2089 typhoon_reset(tp->ioaddr, NoWait); in typhoon_open()
2106 napi_disable(&tp->napi); in typhoon_close()
2112 free_irq(dev->irq, dev); in typhoon_close()
2151 typhoon_reset(tp->ioaddr, NoWait); in typhoon_resume()
2152 return -EBUSY; in typhoon_resume()
2169 if (tp->wol_events & TYPHOON_WAKE_MAGIC_PKT) in typhoon_suspend()
2188 xp_cmd.parm1 = cpu_to_le16(ntohs(*(__be16 *)&dev->dev_addr[0])); in typhoon_suspend()
2189 xp_cmd.parm2 = cpu_to_le32(ntohl(*(__be32 *)&dev->dev_addr[2])); in typhoon_suspend()
2202 if (typhoon_sleep_early(tp, tp->wol_events) < 0) { in typhoon_suspend()
2213 return -EBUSY; in typhoon_suspend()
2236 * The 50usec delay is arbitrary -- it could probably be smaller. in typhoon_test_mmio()
2278 int card_id = (int) ent->driver_data; in typhoon_init_one()
2290 err = -ENOMEM; in typhoon_init_one()
2293 SET_NETDEV_DEV(dev, &pdev->dev); in typhoon_init_one()
2307 err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); in typhoon_init_one()
2317 err = -ENODEV; in typhoon_init_one()
2322 err = -ENODEV; in typhoon_init_one()
2327 err = -ENODEV; in typhoon_init_one()
2332 err = -ENODEV; in typhoon_init_one()
2350 err = -EIO; in typhoon_init_one()
2356 shared = dma_alloc_coherent(&pdev->dev, sizeof(struct typhoon_shared), in typhoon_init_one()
2360 err = -ENOMEM; in typhoon_init_one()
2364 dev->irq = pdev->irq; in typhoon_init_one()
2366 tp->shared = shared; in typhoon_init_one()
2367 tp->shared_dma = shared_dma; in typhoon_init_one()
2368 tp->pdev = pdev; in typhoon_init_one()
2369 tp->tx_pdev = pdev; in typhoon_init_one()
2370 tp->ioaddr = ioaddr; in typhoon_init_one()
2371 tp->tx_ioaddr = ioaddr; in typhoon_init_one()
2372 tp->dev = dev; in typhoon_init_one()
2410 *(__be16 *)&dev->dev_addr[0] = htons(le16_to_cpu(xp_resp[0].parm1)); in typhoon_init_one()
2411 *(__be32 *)&dev->dev_addr[2] = htonl(le32_to_cpu(xp_resp[0].parm2)); in typhoon_init_one()
2413 if (!is_valid_ether_addr(dev->dev_addr)) { in typhoon_init_one()
2415 err = -EIO; in typhoon_init_one()
2429 tp->capabilities = typhoon_card_info[card_id].capabilities; in typhoon_init_one()
2430 tp->xcvr_select = TYPHOON_XCVR_AUTONEG; in typhoon_init_one()
2439 tp->capabilities |= TYPHOON_WAKEUP_NEEDS_RESET; in typhoon_init_one()
2447 /* The chip-specific entries in the device structure. */ in typhoon_init_one()
2448 dev->netdev_ops = &typhoon_netdev_ops; in typhoon_init_one()
2449 netif_napi_add(dev, &tp->napi, typhoon_poll, 16); in typhoon_init_one()
2450 dev->watchdog_timeo = TX_TIMEOUT; in typhoon_init_one()
2452 dev->ethtool_ops = &typhoon_ethtool_ops; in typhoon_init_one()
2458 * on the current 3XP firmware -- it does not respect the offload in typhoon_init_one()
2459 * settings -- so we only allow the user to toggle the TX processing. in typhoon_init_one()
2461 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO | in typhoon_init_one()
2463 dev->features = dev->hw_features | in typhoon_init_one()
2478 dev->dev_addr); in typhoon_init_one()
2510 dma_free_coherent(&pdev->dev, sizeof(struct typhoon_shared), shared, in typhoon_init_one()
2536 typhoon_reset(tp->ioaddr, NoWait); in typhoon_remove_one()
2537 pci_iounmap(pdev, tp->ioaddr); in typhoon_remove_one()
2538 dma_free_coherent(&pdev->dev, sizeof(struct typhoon_shared), in typhoon_remove_one()
2539 tp->shared, tp->shared_dma); in typhoon_remove_one()