Index: stable/11/share/man/man4/ntb_hw.4 =================================================================== --- stable/11/share/man/man4/ntb_hw.4 (revision 323452) +++ stable/11/share/man/man4/ntb_hw.4 (nonexistent) @@ -1,117 +0,0 @@ -.\" -.\" Copyright (c) 2016 Alexander Motin -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd July 28, 2016 -.Dt NTB_HW 4 -.Os -.Sh NAME -.Nm ntb , -.Nm ntb_hw -.Nd Intel(R) Non-Transparent Bridge driver -.Sh SYNOPSIS -To compile this driver into your kernel, -place the following lines in your kernel configuration file: -.Bd -ragged -offset indent -.Cd "device ntb_hw" -.Ed -.Pp -Or, to load the driver as a module at boot, place the following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -ntb_hw_load="YES" -.Ed -.Pp -The following tunables are settable from the -.Xr loader 8 : -.Bl -ohang -.It Va hw.ntb.debug_level -Driver debug level. -The default value is 0, higher means more verbose. -.It Va hint.ntb_hw. Ns Ar X Ns Va .config -Configures NTB resources split between several consumer devices. -Configuration of multiple consumer devices separated by commas. -Each device can be configured as: "[:[:[:]]]", where: -.Va name -is a name of the driver which should attach the device (empty means any), -.Va mw -is a number of memory windows to allocate (empty means all available), -.Va spad -is a number of scratchpad registers to allocate (empty means all available), -.Va db -is a number of doorbells to allocate (empty means all available). -The default configuration is empty string, which means single device -with all available resources allowing any driver attachment. -.El -.Sh DESCRIPTION -The NTB allows you to connect two computer systems using a PCIe link if they -have the correct equipment and connectors. -The -.Nm ntb_hw -driver provides support for the Non-Transparent Bridge (NTB) in the Intel S1200 -and Xeon E3/E5 processor families. -The -.Nm -driver hides hardware details, exposing memory windows, scratchpads and -doorbells via hardware independent KPI. -.Pp -The hardware provides 2-3 memory windows to the other system's memory, -16 scratchpad registers and 14/34 doorbells to interrupt the other system. -On Xeon processors one of memory windows is typically consumed by the driver -to workaround multiple hardware erratas. -.Sh CONFIGURATION -The NTB configuration should be set by BIOS. -It includes enabling NTB, choosing between NTB-to-NTB or NTB-to-Root Port mode, -enabling split BAR mode (one of two 64-bit BARs can be split into two 32-bit -ones) and configuring BAR sizes in bits (from 12 to 29/39) for both NTB sides. -.Pp -The recommended configuration is NTB-to-NTB mode, split bar is enabled and -all BAR sizes are set to 20 (1 MiB). -This needs to be done on both systems. -.Sh SEE ALSO -.Xr ntb_transport 4 , -.Xr if_ntb 4 -.Sh AUTHORS -.An -nosplit -The -.Nm -driver was developed by Intel and originally written by -.An Carl Delsey Aq Mt carl@FreeBSD.org . -Later improvements were done by -.An Conrad E. Meyer Aq Mt cem@FreeBSD.org -and -.An Alexander Motin Aq Mt mav@FreeBSD.org . -.Sh BUGS -NTB-to-Root Port mode is not yet supported, but it doesn't look very useful. -.Pp -On Xeon v2/v3/v4 processors split BAR mode should be enabled to allow -SB01BASE_LOCKUP errata workaround to be applied by the driver. -.Pp -There is no way to protect your system from malicious behavior on the other -system once the link is brought up. -Anyone with root or kernel access on the other system can read or write to -any location on your system. -In other words, only connect two systems that completely trust each other. Property changes on: stable/11/share/man/man4/ntb_hw.4 ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: stable/11/share/man/man4/Makefile =================================================================== --- stable/11/share/man/man4/Makefile (revision 323452) +++ stable/11/share/man/man4/Makefile (revision 323453) @@ -1,993 +1,995 @@ # @(#)Makefile 8.1 (Berkeley) 6/18/93 # $FreeBSD$ .include PACKAGE=runtime-manuals MAN= aac.4 \ aacraid.4 \ acpi.4 \ ${_acpi_asus.4} \ ${_acpi_asus_wmi.4} \ ${_acpi_dock.4} \ ${_acpi_fujitsu.4} \ ${_acpi_hp.4} \ ${_acpi_ibm.4} \ ${_acpi_panasonic.4} \ ${_acpi_rapidstart.4} \ ${_acpi_sony.4} \ acpi_thermal.4 \ ${_acpi_toshiba.4} \ acpi_video.4 \ ${_acpi_wmi.4} \ ada.4 \ adv.4 \ adw.4 \ ae.4 \ ${_aesni.4} \ age.4 \ agp.4 \ aha.4 \ ahb.4 \ ahc.4 \ ahci.4 \ ahd.4 \ ${_aibs.4} \ aio.4 \ alc.4 \ ale.4 \ alpm.4 \ altera_atse.4 \ altera_avgen.4 \ altera_jtag_uart.4 \ altera_sdcard.4 \ altq.4 \ amdpm.4 \ ${_amdsbwd.4} \ ${_amdsmb.4} \ ${_amdtemp.4} \ ${_bxe.4} \ amr.4 \ an.4 \ ${_aout.4} \ ${_apic.4} \ arcmsr.4 \ ${_asmc.4} \ ata.4 \ ath.4 \ ath_ahb.4 \ ath_hal.4 \ ath_pci.4 \ atkbd.4 \ atkbdc.4 \ atp.4 \ ${_atf_test_case.4} \ ${_atrtc.4} \ ${_attimer.4} \ audit.4 \ auditpipe.4 \ aue.4 \ axe.4 \ axge.4 \ bce.4 \ bcma.4 \ bfe.4 \ bge.4 \ ${_bhyve.4} \ bhnd.4 \ bhndb.4 \ bktr.4 \ blackhole.4 \ bnxt.4 \ bpf.4 \ bridge.4 \ bt.4 \ bwi.4 \ bwn.4 \ ${_bytgpio.4} \ capsicum.4 \ cardbus.4 \ carp.4 \ cas.4 \ cc_cdg.4 \ cc_chd.4 \ cc_cubic.4 \ cc_dctcp.4 \ cc_hd.4 \ cc_htcp.4 \ cc_newreno.4 \ cc_vegas.4 \ ${_ccd.4} \ cd.4 \ cdce.4 \ cfi.4 \ cfumass.4 \ ch.4 \ chromebook_platform.4 \ ciss.4 \ cloudabi.4 \ cm.4 \ cmx.4 \ ${_coretemp.4} \ ${_cpuctl.4} \ cpufreq.4 \ crypto.4 \ ctl.4 \ cue.4 \ cxgb.4 \ cxgbe.4 \ cxgbev.4 \ cy.4 \ cyapa.4 \ da.4 \ dc.4 \ dcons.4 \ dcons_crom.4 \ ddb.4 \ de.4 \ devctl.4 \ digi.4 \ disc.4 \ divert.4 \ ${_dpms.4} \ dpt.4 \ ds1307.4 \ ds3231.4 \ ${_dtrace_io.4} \ ${_dtrace_ip.4} \ ${_dtrace_proc.4} \ ${_dtrace_sched.4} \ ${_dtrace_tcp.4} \ ${_dtrace_udp.4} \ dummynet.4 \ ed.4 \ edsc.4 \ ehci.4 \ em.4 \ en.4 \ ena.4 \ enc.4 \ epair.4 \ esp.4 \ est.4 \ et.4 \ etherswitch.4 \ eventtimers.4 \ exca.4 \ fatm.4 \ fd.4 \ fdc.4 \ fdt.4 \ fdtbus.4 \ ffclock.4 \ filemon.4 \ firewire.4 \ fpa.4 \ full.4 \ fwe.4 \ fwip.4 \ fwohci.4 \ fxp.4 \ gbde.4 \ gdb.4 \ gem.4 \ geom.4 \ geom_fox.4 \ geom_linux_lvm.4 \ geom_map.4 \ geom_uzip.4 \ gif.4 \ gpio.4 \ gpioiic.4 \ gpioled.4 \ gre.4 \ h_ertt.4 \ hatm.4 \ hifn.4 \ hme.4 \ hpet.4 \ ${_hpt27xx.4} \ ${_hptiop.4} \ ${_hptmv.4} \ ${_hptnr.4} \ ${_hptrr.4} \ ${_hv_kvp.4} \ ${_hv_netvsc.4} \ ${_hv_storvsc.4} \ ${_hv_utils.4} \ ${_hv_vmbus.4} \ hv_vss.4 \ hwpmc.4 \ ichsmb.4 \ ${_ichwd.4} \ icmp.4 \ icmp6.4 \ ida.4 \ if_ipsec.4 \ ifmib.4 \ ig4.4 \ igb.4 \ igmp.4 \ iic.4 \ iicbb.4 \ iicbus.4 \ iicsmb.4 \ iir.4 \ inet.4 \ inet6.4 \ intpm.4 \ intro.4 \ ${_io.4} \ ${_ioat.4} \ ip.4 \ ip6.4 \ ipfirewall.4 \ ipheth.4 \ ${_ipmi.4} \ ips.4 \ ipsec.4 \ ipw.4 \ ipwfw.4 \ isci.4 \ isl.4 \ ismt.4 \ isp.4 \ ispfw.4 \ iwi.4 \ iwifw.4 \ iwm.4 \ iwmfw.4 \ iwn.4 \ iwnfw.4 \ ixgb.4 \ ixgbe.4 \ ixl.4 \ ixlv.4 \ jedec_ts.4 \ jme.4 \ joy.4 \ kbdmux.4 \ keyboard.4 \ kld.4 \ ksyms.4 \ ktr.4 \ kue.4 \ lagg.4 \ le.4 \ led.4 \ lge.4 \ ${_linux.4} \ lm75.4 \ lmc.4 \ lo.4 \ lp.4 \ lpbb.4 \ lpt.4 \ mac.4 \ mac_biba.4 \ mac_bsdextended.4 \ mac_ifoff.4 \ mac_lomac.4 \ mac_mls.4 \ mac_none.4 \ mac_partition.4 \ mac_portacl.4 \ mac_seeotheruids.4 \ mac_stub.4 \ mac_test.4 \ malo.4 \ mcd.4 \ md.4 \ mdio.4 \ me.4 \ mem.4 \ meteor.4 \ mfi.4 \ miibus.4 \ mk48txx.4 \ mld.4 \ mlx.4 \ mlx4en.4 \ mlx5en.4 \ mly.4 \ mmc.4 \ mmcsd.4 \ mn.4 \ mod_cc.4 \ mos.4 \ mouse.4 \ mpr.4 \ mps.4 \ mpt.4 \ mrsas.4 \ msk.4 \ mtio.4 \ multicast.4 \ mvs.4 \ mwl.4 \ mwlfw.4 \ mxge.4 \ my.4 \ nand.4 \ nandsim.4 \ natm.4 \ natmip.4 \ ncr.4 \ ncv.4 \ ${_ndis.4} \ net80211.4 \ netfpga10g_nf10bmac.4 \ netgraph.4 \ netintro.4 \ netmap.4 \ ${_nfe.4} \ ${_nfsmb.4} \ ng_async.4 \ ng_atm.4 \ ngatmbase.4 \ ng_atmllc.4 \ ng_bpf.4 \ ng_bridge.4 \ ng_bt3c.4 \ ng_btsocket.4 \ ng_car.4 \ ng_ccatm.4 \ ng_cisco.4 \ ng_deflate.4 \ ng_device.4 \ nge.4 \ ng_echo.4 \ ng_eiface.4 \ ng_etf.4 \ ng_ether.4 \ ng_ether_echo.4 \ ng_frame_relay.4 \ ng_gif.4 \ ng_gif_demux.4 \ ng_h4.4 \ ng_hci.4 \ ng_hole.4 \ ng_hub.4 \ ng_iface.4 \ ng_ipfw.4 \ ng_ip_input.4 \ ng_ksocket.4 \ ng_l2cap.4 \ ng_l2tp.4 \ ng_lmi.4 \ ng_mppc.4 \ ng_nat.4 \ ng_netflow.4 \ ng_one2many.4 \ ng_patch.4 \ ng_ppp.4 \ ng_pppoe.4 \ ng_pptpgre.4 \ ng_pred1.4 \ ng_rfc1490.4 \ ng_socket.4 \ ng_source.4 \ ng_split.4 \ ng_sppp.4 \ ng_sscfu.4 \ ng_sscop.4 \ ng_tag.4 \ ng_tcpmss.4 \ ng_tee.4 \ ng_tty.4 \ ng_ubt.4 \ ng_UI.4 \ ng_uni.4 \ ng_vjc.4 \ ng_vlan.4 \ nmdm.4 \ nsp.4 \ - ${_ntb_hw.4} \ + ${_ntb.4} \ + ${_ntb_hw_intel.4} \ + ${_ntb_hw_plx.4} \ ${_ntb_transport.4} \ ${_if_ntb.4} \ null.4 \ numa.4 \ ${_nvd.4} \ ${_nvme.4} \ ${_nvram.4} \ ${_nvram2env.4} \ ${_nxge.4} \ oce.4 \ ohci.4 \ orm.4 \ ow.4 \ ow_temp.4 \ owc.4 \ ${_padlock.4} \ pass.4 \ patm.4 \ pccard.4 \ pccbb.4 \ pcf.4 \ pci.4 \ pcib.4 \ pcic.4 \ pcm.4 \ pcn.4 \ ${_pf.4} \ ${_pflog.4} \ ${_pfsync.4} \ pim.4 \ pms.4 \ polling.4 \ ppbus.4 \ ppc.4 \ ppi.4 \ procdesc.4 \ proto.4 \ psm.4 \ pst.4 \ pt.4 \ pts.4 \ pty.4 \ puc.4 \ ${_qlxge.4} \ ${_qlxgb.4} \ ${_qlxgbe.4} \ ${_qlnxe.4} \ ral.4 \ random.4 \ rc.4 \ rctl.4 \ re.4 \ rgephy.4 \ rights.4 \ rl.4 \ rndtest.4 \ route.4 \ rp.4 \ rtwn.4 \ rtwnfw.4 \ rue.4 \ rum.4 \ run.4 \ runfw.4 \ sa.4 \ safe.4 \ sbp.4 \ sbp_targ.4 \ scc.4 \ scd.4 \ sched_4bsd.4 \ sched_ule.4 \ screen.4 \ scsi.4 \ sctp.4 \ sdhci.4 \ sem.4 \ send.4 \ ses.4 \ sf.4 \ ${_sfxge.4} \ sge.4 \ si.4 \ siba.4 \ siftr.4 \ siis.4 \ simplebus.4 \ sio.4 \ sis.4 \ sk.4 \ smb.4 \ smbus.4 \ smp.4 \ smsc.4 \ sn.4 \ snd_ad1816.4 \ snd_als4000.4 \ snd_atiixp.4 \ snd_cmi.4 \ snd_cs4281.4 \ snd_csa.4 \ snd_ds1.4 \ snd_emu10k1.4 \ snd_emu10kx.4 \ snd_envy24.4 \ snd_envy24ht.4 \ snd_es137x.4 \ snd_ess.4 \ snd_fm801.4 \ snd_gusc.4 \ snd_hda.4 \ snd_hdspe.4 \ snd_ich.4 \ snd_maestro3.4 \ snd_maestro.4 \ snd_mss.4 \ snd_neomagic.4 \ snd_sbc.4 \ snd_solo.4 \ snd_spicds.4 \ snd_t4dwave.4 \ snd_uaudio.4 \ snd_via8233.4 \ snd_via82c686.4 \ snd_vibes.4 \ snp.4 \ spic.4 \ ${_spkr.4} \ splash.4 \ sppp.4 \ ste.4 \ stf.4 \ stg.4 \ stge.4 \ sym.4 \ syncache.4 \ syncer.4 \ syscons.4 \ sysmouse.4 \ tap.4 \ targ.4 \ tcp.4 \ tdfx.4 \ terasic_mtl.4 \ termios.4 \ textdump.4 \ ti.4 \ timecounters.4 \ tl.4 \ ${_tpm.4} \ trm.4 \ tty.4 \ tun.4 \ twa.4 \ twe.4 \ tws.4 \ tx.4 \ txp.4 \ udp.4 \ udplite.4 \ ure.4 \ vale.4 \ vga.4 \ vge.4 \ viapm.4 \ ${_viawd.4} \ ${_virtio.4} \ ${_virtio_balloon.4} \ ${_virtio_blk.4} \ ${_virtio_console.4} \ ${_virtio_random.4} \ ${_virtio_scsi.4} \ vkbd.4 \ vlan.4 \ vxlan.4 \ ${_vmx.4} \ vpo.4 \ vr.4 \ vt.4 \ vte.4 \ ${_vtnet.4} \ ${_vxge.4} \ watchdog.4 \ wb.4 \ ${_wbwd.4} \ wi.4 \ witness.4 \ wlan.4 \ wlan_acl.4 \ wlan_amrr.4 \ wlan_ccmp.4 \ wlan_tkip.4 \ wlan_wep.4 \ wlan_xauth.4 \ ${_wpi.4} \ wsp.4 \ xe.4 \ ${_xen.4} \ xhci.4 \ xl.4 \ ${_xnb.4} \ xpt.4 \ zero.4 \ zyd.4 MLINKS= ae.4 if_ae.4 MLINKS+=age.4 if_age.4 MLINKS+=agp.4 agpgart.4 MLINKS+=alc.4 if_alc.4 MLINKS+=ale.4 if_ale.4 MLINKS+=altera_atse.4 atse.4 MLINKS+=altera_sdcard.4 altera_sdcardc.4 MLINKS+=altq.4 ALTQ.4 MLINKS+=ath.4 if_ath.4 MLINKS+=ath_pci.4 if_ath_pci.4 MLINKS+=an.4 if_an.4 MLINKS+=aue.4 if_aue.4 MLINKS+=axe.4 if_axe.4 MLINKS+=bce.4 if_bce.4 MLINKS+=bfe.4 if_bfe.4 MLINKS+=bge.4 if_bge.4 MLINKS+=bktr.4 brooktree.4 MLINKS+=bnxt.4 if_bnxt.4 MLINKS+=bridge.4 if_bridge.4 MLINKS+=bwi.4 if_bwi.4 MLINKS+=bwn.4 if_bwn.4 MLINKS+=${_bxe.4} ${_if_bxe.4} MLINKS+=cas.4 if_cas.4 MLINKS+=cdce.4 if_cdce.4 MLINKS+=cfi.4 cfid.4 MLINKS+=cloudabi.4 cloudabi64.4 MLINKS+=crypto.4 cryptodev.4 MLINKS+=cue.4 if_cue.4 MLINKS+=cxgb.4 if_cxgb.4 MLINKS+=cxgbe.4 if_cxgbe.4 \ cxgbe.4 vcxgbe.4 \ cxgbe.4 if_vcxgbe.4 \ cxgbe.4 cxl.4 \ cxgbe.4 if_cxl.4 \ cxgbe.4 vcxl.4 \ cxgbe.4 if_vcxl.4 \ cxgbe.4 cc.4 \ cxgbe.4 if_cc.4 \ cxgbe.4 vcc.4 \ cxgbe.4 if_vcc.4 MLINKS+=cxgbev.4 if_cxgbev.4 \ cxgbev.4 cxlv.4 \ cxgbev.4 if_cxlv.4 \ cxgbev.4 ccv.4 \ cxgbev.4 if_ccv.4 MLINKS+=dc.4 if_dc.4 MLINKS+=de.4 if_de.4 MLINKS+=disc.4 if_disc.4 MLINKS+=ed.4 if_ed.4 MLINKS+=edsc.4 if_edsc.4 MLINKS+=em.4 if_em.4 MLINKS+=en.4 if_en.4 MLINKS+=enc.4 if_enc.4 MLINKS+=epair.4 if_epair.4 MLINKS+=et.4 if_et.4 MLINKS+=fatm.4 if_fatm.4 MLINKS+=fd.4 stderr.4 \ fd.4 stdin.4 \ fd.4 stdout.4 MLINKS+=fdt.4 FDT.4 MLINKS+=firewire.4 ieee1394.4 MLINKS+=fpa.4 fea.4 MLINKS+=fwe.4 if_fwe.4 MLINKS+=fwip.4 if_fwip.4 MLINKS+=fxp.4 if_fxp.4 MLINKS+=gem.4 if_gem.4 MLINKS+=geom.4 GEOM.4 MLINKS+=gif.4 if_gif.4 MLINKS+=gpio.4 gpiobus.4 MLINKS+=gre.4 if_gre.4 MLINKS+=hatm.4 if_hatm.4 MLINKS+=hme.4 if_hme.4 MLINKS+=hpet.4 acpi_hpet.4 MLINKS+=${_hptrr.4} ${_rr232x.4} MLINKS+=${_attimer.4} ${_i8254.4} MLINKS+=igb.4 if_igb.4 MLINKS+=ip.4 rawip.4 MLINKS+=ipfirewall.4 ipaccounting.4 \ ipfirewall.4 ipacct.4 \ ipfirewall.4 ipfw.4 MLINKS+=ipheth.4 if_ipheth.4 MLINKS+=ipw.4 if_ipw.4 MLINKS+=iwi.4 if_iwi.4 MLINKS+=iwm.4 if_iwm.4 MLINKS+=iwn.4 if_iwn.4 MLINKS+=ixgb.4 if_ixgb.4 MLINKS+=ixgbe.4 ix.4 MLINKS+=ixgbe.4 if_ix.4 MLINKS+=ixgbe.4 if_ixgbe.4 MLINKS+=ixl.4 if_ixl.4 MLINKS+=ixlv.4 if_ixlv.4 MLINKS+=jme.4 if_jme.4 MLINKS+=kue.4 if_kue.4 MLINKS+=lagg.4 trunk.4 MLINKS+=lagg.4 if_lagg.4 MLINKS+=le.4 if_le.4 MLINKS+=lge.4 if_lge.4 MLINKS+=lmc.4 if_lmc.4 MLINKS+=lo.4 loop.4 MLINKS+=lp.4 plip.4 MLINKS+=malo.4 if_malo.4 MLINKS+=md.4 vn.4 MLINKS+=mem.4 kmem.4 MLINKS+=mfi.4 mfi_linux.4 \ mfi.4 mfip.4 MLINKS+=mlx5en.4 mce.4 MLINKS+=mn.4 if_mn.4 MLINKS+=mos.4 if_mos.4 MLINKS+=msk.4 if_msk.4 MLINKS+=mwl.4 if_mwl.4 MLINKS+=mxge.4 if_mxge.4 MLINKS+=my.4 if_my.4 MLINKS+=${_ndis.4} ${_if_ndis.4} MLINKS+=netfpga10g_nf10bmac.4 if_nf10bmac.4 MLINKS+=netintro.4 net.4 \ netintro.4 networking.4 MLINKS+=${_nfe.4} ${_if_nfe.4} MLINKS+=nge.4 if_nge.4 -MLINKS+=${_ntb_hw.4} ${_ntb.4} MLINKS+=${_nxge.4} ${_if_nxge.4} MLINKS+=ow.4 onewire.4 MLINKS+=patm.4 if_patm.4 MLINKS+=pccbb.4 cbb.4 MLINKS+=pcm.4 snd.4 \ pcm.4 sound.4 MLINKS+=pcn.4 if_pcn.4 MLINKS+=pms.4 pmspcv.4 MLINKS+=ral.4 if_ral.4 MLINKS+=re.4 if_re.4 MLINKS+=rl.4 if_rl.4 MLINKS+=rue.4 if_rue.4 MLINKS+=rum.4 if_rum.4 MLINKS+=run.4 if_run.4 MLINKS+=scsi.4 CAM.4 \ scsi.4 cam.4 \ scsi.4 scbus.4 \ scsi.4 SCSI.4 MLINKS+=sf.4 if_sf.4 MLINKS+=sge.4 if_sge.4 MLINKS+=sis.4 if_sis.4 MLINKS+=sk.4 if_sk.4 MLINKS+=smp.4 SMP.4 MLINKS+=smsc.4 if_smsc.4 MLINKS+=sn.4 if_sn.4 MLINKS+=snd_envy24.4 snd_ak452x.4 MLINKS+=snd_sbc.4 snd_sb16.4 \ snd_sbc.4 snd_sb8.4 MLINKS+=${_spkr.4} ${_speaker.4} MLINKS+=splash.4 screensaver.4 MLINKS+=ste.4 if_ste.4 MLINKS+=stf.4 if_stf.4 MLINKS+=stge.4 if_stge.4 MLINKS+=syncache.4 syncookies.4 MLINKS+=syscons.4 sc.4 MLINKS+=tap.4 if_tap.4 MLINKS+=tdfx.4 tdfx_linux.4 MLINKS+=ti.4 if_ti.4 MLINKS+=tl.4 if_tl.4 MLINKS+=tun.4 if_tun.4 MLINKS+=tx.4 if_tx.4 MLINKS+=txp.4 if_txp.4 MLINKS+=ure.4 if_ure.4 MLINKS+=vge.4 if_vge.4 MLINKS+=vlan.4 if_vlan.4 MLINKS+=vxlan.4 if_vxlan.4 MLINKS+=${_vmx.4} ${_if_vmx.4} MLINKS+=vpo.4 imm.4 MLINKS+=vr.4 if_vr.4 MLINKS+=vte.4 if_vte.4 MLINKS+=${_vtnet.4} ${_if_vtnet.4} MLINKS+=${_vxge.4} ${_if_vxge.4} MLINKS+=watchdog.4 SW_WATCHDOG.4 MLINKS+=wb.4 if_wb.4 MLINKS+=wi.4 if_wi.4 MLINKS+=${_wpi.4} ${_if_wpi.4} MLINKS+=xe.4 if_xe.4 MLINKS+=xl.4 if_xl.4 MLINKS+=zyd.4 if_zyd.4 .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" _acpi_asus.4= acpi_asus.4 _acpi_asus_wmi.4= acpi_asus_wmi.4 _acpi_dock.4= acpi_dock.4 _acpi_fujitsu.4=acpi_fujitsu.4 _acpi_hp.4= acpi_hp.4 _acpi_ibm.4= acpi_ibm.4 _acpi_panasonic.4=acpi_panasonic.4 _acpi_rapidstart.4=acpi_rapidstart.4 _acpi_sony.4= acpi_sony.4 _acpi_toshiba.4=acpi_toshiba.4 _acpi_wmi.4= acpi_wmi.4 _aesni.4= aesni.4 _aout.4= aout.4 _apic.4= apic.4 _atrtc.4= atrtc.4 _attimer.4= attimer.4 _aibs.4= aibs.4 _amdsbwd.4= amdsbwd.4 _amdsmb.4= amdsmb.4 _amdtemp.4= amdtemp.4 _asmc.4= asmc.4 _bxe.4= bxe.4 _bytgpio.4= bytgpio.4 _coretemp.4= coretemp.4 _cpuctl.4= cpuctl.4 _dpms.4= dpms.4 _hpt27xx.4= hpt27xx.4 _hptiop.4= hptiop.4 _hptmv.4= hptmv.4 _hptnr.4= hptnr.4 _hptrr.4= hptrr.4 _hv_kvp.4= hv_kvp.4 _hv_netvsc.4= hv_netvsc.4 _hv_storvsc.4= hv_storvsc.4 _hv_utils.4= hv_utils.4 _hv_vmbus.4= hv_vmbus.4 _i8254.4= i8254.4 _ichwd.4= ichwd.4 _if_bxe.4= if_bxe.4 _if_ndis.4= if_ndis.4 _if_nfe.4= if_nfe.4 _if_nxge.4= if_nxge.4 _if_urtw.4= if_urtw.4 _if_vmx.4= if_vmx.4 _if_vtnet.4= if_vtnet.4 _if_vxge.4= if_vxge.4 _if_wpi.4= if_wpi.4 _ipmi.4= ipmi.4 _io.4= io.4 _linux.4= linux.4 _ndis.4= ndis.4 _nfe.4= nfe.4 _nfsmb.4= nfsmb.4 _nvd.4= nvd.4 _nvme.4= nvme.4 _nvram.4= nvram.4 _nxge.4= nxge.4 _virtio.4= virtio.4 _virtio_balloon.4=virtio_balloon.4 _virtio_blk.4= virtio_blk.4 _virtio_console.4=virtio_console.4 _virtio_random.4= virtio_random.4 _virtio_scsi.4= virtio_scsi.4 _vmx.4= vmx.4 _vtnet.4= vtnet.4 _vxge.4= vxge.4 _padlock.4= padlock.4 _rr232x.4= rr232x.4 _speaker.4= speaker.4 _spkr.4= spkr.4 _tpm.4= tpm.4 _urtw.4= urtw.4 _viawd.4= viawd.4 _wbwd.4= wbwd.4 _wpi.4= wpi.4 _xen.4= xen.4 _xnb.4= xnb.4 .endif .if ${MACHINE_CPUARCH} == "amd64" _if_ntb.4= if_ntb.4 _ioat.4= ioat.4 _ntb.4= ntb.4 -_ntb_hw.4= ntb_hw.4 +_ntb_hw_intel.4= ntb_hw_intel.4 +_ntb_hw_plx.4= ntb_hw_plx.4 _ntb_transport.4=ntb_transport.4 _qlxge.4= qlxge.4 _qlxgb.4= qlxgb.4 _qlxgbe.4= qlxgbe.4 _qlnxe.4= qlnxe.4 _sfxge.4= sfxge.4 MLINKS+=qlxge.4 if_qlxge.4 MLINKS+=qlxgb.4 if_qlxgb.4 MLINKS+=qlxgbe.4 if_qlxgbe.4 MLINKS+=qlnxe.4 if_qlnxe.4 MLINKS+=sfxge.4 if_sfxge.4 .if ${MK_BHYVE} != "no" _bhyve.4= bhyve.4 .endif .endif .if ${MACHINE_CPUARCH} == "mips" _nvram2env.4= nvram2env.4 .endif .if exists(${.CURDIR}/man4.${MACHINE_CPUARCH}) SUBDIR= man4.${MACHINE_CPUARCH} .endif .if ${MK_BLUETOOTH} != "no" MAN+= ng_bluetooth.4 .endif .if ${MK_CCD} != "no" _ccd.4= ccd.4 .endif .if ${MK_CDDL} != "no" _dtrace_io.4= dtrace_io.4 _dtrace_ip.4= dtrace_ip.4 _dtrace_proc.4= dtrace_proc.4 _dtrace_sched.4= dtrace_sched.4 _dtrace_tcp.4= dtrace_tcp.4 _dtrace_udp.4= dtrace_udp.4 .endif .if ${MK_ISCSI} != "no" MAN+= cfiscsi.4 MAN+= iscsi.4 MAN+= iscsi_initiator.4 MAN+= iser.4 .endif .if ${MK_OFED} != "no" MAN+= mlx4ib.4 MAN+= mlx5ib.4 .endif .if ${MK_TESTS} != "no" ATF= ${.CURDIR}/../../../contrib/atf .PATH: ${ATF}/doc _atf_test_case.4= atf-test-case.4 .endif .if ${MK_PF} != "no" _pf.4= pf.4 _pflog.4= pflog.4 _pfsync.4= pfsync.4 .endif .if ${MK_USB} != "no" MAN+= \ otus.4 \ otusfw.4 \ rsu.4 \ rsufw.4 \ u3g.4 \ uark.4 \ uart.4 \ uath.4 \ ubsa.4 \ ubsec.4 \ ubser.4 \ ubtbcmfw.4 \ uchcom.4 \ ucom.4 \ ucycom.4 \ udav.4 \ udbp.4 \ udl.4 \ uep.4 \ ufm.4 \ ufoma.4 \ uftdi.4 \ ugen.4 \ ugold.4 \ uhci.4 \ uhid.4 \ uhso.4 \ uipaq.4 \ ukbd.4 \ uled.4 \ ulpt.4 \ umass.4 \ umcs.4 \ umct.4 \ umodem.4 \ umoscom.4 \ ums.4 \ unix.4 \ upgt.4 \ uplcom.4 \ ural.4 \ urio.4 \ urndis.4 \ ${_urtw.4} \ urtwn.4 \ urtwnfw.4 \ usb.4 \ usb_quirk.4 \ usb_template.4 \ usfs.4 \ uslcom.4 \ utopia.4 \ uvisor.4 \ uvscom.4 \ MLINKS+=otus.4 if_otus.4 MLINKS+=rsu.4 if_rsu.4 MLINKS+=u3g.4 u3gstub.4 MLINKS+=uath.4 if_uath.4 MLINKS+=udav.4 if_udav.4 MLINKS+=upgt.4 if_upgt.4 MLINKS+=ural.4 if_ural.4 MLINKS+=urndis.4 if_urndis.4 MLINKS+=${_urtw.4} ${_if_urtw.4} MLINKS+=urtwn.4 if_urtwn.4 .endif .include Index: stable/11/share/man/man4/if_ntb.4 =================================================================== --- stable/11/share/man/man4/if_ntb.4 (revision 323452) +++ stable/11/share/man/man4/if_ntb.4 (revision 323453) @@ -1,89 +1,89 @@ .\" .\" Copyright (c) 2016 Alexander Motin .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd July 29, 2016 +.Dd September 2, 2017 .Dt IF_NTB 4 .Os .Sh NAME .Nm if_ntb .Nd Virtual Ethernet interface for Non-Transparent Bridges .Sh SYNOPSIS To compile this driver into your kernel, place the following lines in your kernel configuration file: .Bd -ragged -offset indent +.Cd "device ntb" +.Cd "device ntb_transport" .Cd "device if_ntb" .Ed .Pp Or, to load the driver as a module at boot, place the following line in .Xr loader.conf 5 : .Bd -literal -offset indent if_ntb_load="YES" .Ed .Pp The following tunables are settable from the .Xr loader 8 : .Bl -ohang .It Va hw.if_ntb.num_queues -Number of transport queues to use per interface. +Limits maximal number of queues per interface. Default is unlimited. .El .Sh DESCRIPTION The .Nm driver attaches on top of the .Xr ntb_transport 4 -driver to utilize its resources to create virtual Ethernet interface between -the systems. -Interface capabilities depend on the underlying transport. -Typical MTU is about 64KB to reduce overhead. -By default one queue is used, but more may be configured. -The MAC address for interface is randomly generated. +driver to utilize one or more of its packet queues to create virtual +Ethernet network interface between the systems. +Typical MTU for the interface is about 64KB to reduce overhead. +Default MAC address for the interface is randomly generated. .Pp The .Nm driver does not implement any real hardware offload, but since PCIe link is protected by CRC32, in some situations it may be possible to save some CPU cycles by enabling fake checksum offload on both link sides via setting .Cm rxcsum and .Cm txcsum interface options. .Sh SEE ALSO .Xr ntb_transport 4 .Sh AUTHORS .An -nosplit The .Nm driver was developed by Intel and originally written by .An Carl Delsey Aq Mt carl@FreeBSD.org . Later improvements were done by .An Conrad E. Meyer Aq Mt cem@FreeBSD.org and .An Alexander Motin Aq Mt mav@FreeBSD.org . .Sh BUGS Linux supports only one queue per interface, so manual configuration may be required for compatibility. Index: stable/11/share/man/man4/ntb.4 =================================================================== --- stable/11/share/man/man4/ntb.4 (nonexistent) +++ stable/11/share/man/man4/ntb.4 (revision 323453) @@ -0,0 +1,91 @@ +.\" +.\" Copyright (c) 2017 Alexander Motin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd September 2, 2017 +.Dt NTB 4 +.Os +.Sh NAME +.Nm ntb +.Nd Non-Transparent Bridge subsystem +.Sh SYNOPSIS +To compile it into your kernel, +place the following lines in your kernel configuration file: +.Bd -ragged -offset indent +.Cd "device ntb" +.Ed +.Pp +Or, to load it as a module at boot, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +ntb_load="YES" +.Ed +.Pp +The following tunables are settable from the +.Xr loader 8 : +.Bl -ohang +.It Va hw.ntb.debug_level +Driver debug level. +The default value is 0, higher means more verbose. +.It Va hint.ntb_hw. Ns Ar X Ns Va .config +Configures a set of NTB functions, separated by commas, +and their resource allocation. +Each function can be configured as: "[][:[:[:]]]", where: +.Va name +is a name of the driver to attach (empty means any), +.Va mw +is a number of memory windows to allocate (empty means all available), +.Va spad +is a number of scratchpad registers to allocate (empty means all available), +.Va db +is a number of doorbells to allocate (empty means all available). +The default configuration is empty string, which means single function +with all available resources, allowing any driver to attach. +.El +.Sh DESCRIPTION +Non-Transparent Bridges allow to connect two computer systems with PCIe +link(s), providing each of them limited access to others memory space, +scratchpad registers and interrupts. +The +.Nm +subsystem uses those resources provided in generic way by hardware drivers +and splits them between several functions, according to specified +configuration. +.Sh SEE ALSO +.Xr if_ntb 4 , +.Xr ntb_transport 4 , +.Xr ntb_hw_intel 4 , +.Xr ntb_hw_plx 4 +.Sh AUTHORS +.An -nosplit +The +.Nm +subsystem was developed by Intel and originally written by +.An Carl Delsey Aq Mt carl@FreeBSD.org . +Later improvements were done by +.An Conrad E. Meyer Aq Mt cem@FreeBSD.org +and +.An Alexander Motin Aq Mt mav@FreeBSD.org . Property changes on: stable/11/share/man/man4/ntb.4 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/share/man/man4/ntb_hw_intel.4 =================================================================== --- stable/11/share/man/man4/ntb_hw_intel.4 (nonexistent) +++ stable/11/share/man/man4/ntb_hw_intel.4 (revision 323453) @@ -0,0 +1,97 @@ +.\" +.\" Copyright (c) 2016-2017 Alexander Motin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 30, 2017 +.Dt NTB_HW_INTEL 4 +.Os +.Sh NAME +.Nm ntb_hw_intel +.Nd Intel(R) Non-Transparent Bridge driver +.Sh SYNOPSIS +To compile this driver into your kernel, +place the following lines in your kernel configuration file: +.Bd -ragged -offset indent +.Cd "device ntb" +.Cd "device ntb_hw_intel" +.Ed +.Pp +Or, to load the driver as a module at boot, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +ntb_hw_intel_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm ntb_hw_intel +driver provides support for the Non-Transparent Bridge (NTB) hardware in +Intel Xeon E3/E5 and S1200 processor families, which allow one of their PCIe +ports to be switched from transparent to non-transparent bridge mode. +In this mode bridge looks not as a PCI bridge, but as PCI endpoint device. +The driver hides hardware details, exposing memory windows, scratchpads +and doorbells of the other side via hardware independent KPI to +.Xr ntb 4 +subsystem. +.Pp +The hardware provides 2 or 3 memory windows to the other system's memory, +16 scratchpad registers and 14 or 34 doorbells to interrupt the other system. +On Xeon processors one of memory windows is typically consumed by the driver +itself to workaround multiple hardware erratas. +.Sh CONFIGURATION +The NTB configuration should be set by BIOS. +It includes enabling NTB, choosing between NTB-to-NTB (back-to-back) or +NTB-to-Root Port mode, +enabling split BAR mode (one of two 64-bit BARs can be split into two 32-bit +ones) and configuring BAR sizes in bits (from 12 to 29/39) for both NTB sides. +.Pp +The recommended configuration is NTB-to-NTB mode, split bar is enabled and +all BAR sizes are set to 20 (1 MiB). +This needs to be done on both systems. +.Sh SEE ALSO +.Xr if_ntb 4 , +.Xr ntb_transport 4 , +.Xr ntb 4 , +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was developed by Intel and originally written by +.An Carl Delsey Aq Mt carl@FreeBSD.org . +Later improvements were done by +.An Conrad E. Meyer Aq Mt cem@FreeBSD.org +and +.An Alexander Motin Aq Mt mav@FreeBSD.org . +.Sh BUGS +NTB-to-Root Port mode is not yet supported, but it doesn't look very useful. +.Pp +On Xeon v2/v3/v4 processors split BAR mode should be enabled to allow +SB01BASE_LOCKUP errata workaround to be applied by the driver. +.Pp +There is no way to protect your system from malicious behavior on the other +system once the link is brought up. +Anyone with root or kernel access on the other system can read or write to +any location on your system. +In other words, only connect two systems that completely trust each other. Property changes on: stable/11/share/man/man4/ntb_hw_intel.4 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/share/man/man4/ntb_hw_plx.4 =================================================================== --- stable/11/share/man/man4/ntb_hw_plx.4 (nonexistent) +++ stable/11/share/man/man4/ntb_hw_plx.4 (revision 323453) @@ -0,0 +1,118 @@ +.\" +.\" Copyright (c) 2017 Alexander Motin +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd August 30, 2017 +.Dt NTB_HW_PLX 4 +.Os +.Sh NAME +.Nm ntb_hw_plx +.Nd PLX/Avago/Broadcom Non-Transparent Bridge driver +.Sh SYNOPSIS +To compile this driver into your kernel, +place the following lines in your kernel configuration file: +.Bd -ragged -offset indent +.Cd "device ntb" +.Cd "device ntb_hw_plx" +.Ed +.Pp +Or, to load the driver as a module at boot, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +ntb_hw_plx_load="YES" +.Ed +.Pp +The following tunables are settable from the +.Xr loader 8 : +.Bl -ohang +.It Va hint.ntb_hw. Ns Ar X Ns Va .b2b +Being set to 1 (default) tells the driver attached to Virtual Interface of the +NTB that it works in NTB-to-NTB (back-to-back) mode, 0 -- NTB-to-Root Port. +Driver attached to Link Interface (visible from Root Port side) switches to +NTB-to-Root Port mode automatically, but one attached to Virtual Interface +can't detect what is on the other side and require external knowledge. +.El +.Sh DESCRIPTION +The +.Nm +driver provides support for the Non-Transparent Bridge (NTB) hardware in +PLX PCIe bridge chips, which allow up to two of their PCIe ports to be +switched from transparent to non-transparent bridge mode. +In this mode bridge looks not as a PCI bridge, but as PCI endpoint device. +The driver hides hardware details, exposing memory windows, scratchpads +and doorbells of the other side via hardware independent KPI to +.Xr ntb 4 +subsystem. +.Pp +Each PLX NTB provides up to 2 64-bit or 4 32-bit memory windows to the +other system's memory, 6 or 12 scratchpad registers and 16 doorbells to +interrupt the other system. +In NTB-to-NTB mode one of memory windows (or half of it, if bigger then 1MB) +is consumed by the driver itself to access scratchpad and doorbell registers +of the other side. +.Sh HARDWARE +The following PLX/Avago/Broadcom chips are supported by the +.Nm +driver: +.Pp +.Bl -bullet -compact +.It +PEX 8713 +.It +PEX 8717 +.It +PEX 8725 +.It +PEX 8733 +.It +PEX 8749 +.El +.Pp +, but it may also work with other compatible ones. +.Sh CONFIGURATION +The basic chip configuration should be done by serial EEPROM or via i2c. +It includes enabling NTB on one or both sides (choosing between NTB-to-NTB +(back-to-back) and NTB-to-Root Port modes) and configuring BARs sizes. +.Pp +The recommended mode is NTB-to-NTB mode, since while NTB-to-Root Port is +generally supported by the driver, it require PCI hotplug handling on the +Root Port, that may be difficult or cause different kinds of problems. +.Sh SEE ALSO +.Xr if_ntb 4 , +.Xr ntb_transport 4 , +.Xr ntb 4 , +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written by +.An Alexander Motin Aq Mt mav@FreeBSD.org . +.Sh BUGS +There is no way to protect your system from malicious behavior on the other +system once the link is brought up. +Anyone with root or kernel access on the other system can read or write to +any location on your system. +In other words, only connect two systems that completely trust each other. Property changes on: stable/11/share/man/man4/ntb_hw_plx.4 ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/share/man/man4/ntb_transport.4 =================================================================== --- stable/11/share/man/man4/ntb_transport.4 (revision 323452) +++ stable/11/share/man/man4/ntb_transport.4 (revision 323453) @@ -1,79 +1,102 @@ .\" -.\" Copyright (c) 2016 Alexander Motin +.\" Copyright (c) 2016-2017 Alexander Motin .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" $FreeBSD$ .\" -.Dd July 29, 2016 +.Dd September 2, 2017 .Dt NTB_TRANSPORT 4 .Os .Sh NAME .Nm ntb_transport .Nd Packet-oriented transport for Non-Transparent Bridges .Sh SYNOPSIS -To load the driver as a module at boot, place the following line in +To compile this driver into your kernel, +place the following lines in your kernel configuration file: +.Bd -ragged -offset indent +.Cd "device ntb" +.Cd "device ntb_transport" +.Ed +.Pp +Or, to load the driver as a module at boot, place the following line in .Xr loader.conf 5 : .Bd -literal -offset indent ntb_transport_load="YES" .Ed .Pp The following tunables are settable from the .Xr loader 8 : .Bl -ohang .It Va hw.ntb_transport.debug_level Driver debug level. The default value is 0, higher means more verbose. .It Va hint.ntb_transport. Ns Ar X Ns Va .config -Configures queues allocation for consumer devices, separated by commas. -Each device can be configured as: "[:]", where: +Configures a set of the transport consumers, separated by commas. +Each consumer can be configured as: "[][:]", where: .Va name -is a name of the driver which should attach the device (empty means any), +is a name of the driver to attach (empty means any), .Va queues -is a number of queues to allocate (empty means automatic), -The default configuration is empty string, which means single device -with one queue per memory window allowing any driver attachment. +is a number of queues to allocate (empty means automatic). +The default configuration is empty string, which means single consumer +with one queue per memory window, allowing any driver to attach. .El .Sh DESCRIPTION The .Nm driver attaches on top of the .Nm ntb -driver to utilize its resources to create set of bidirectional queues, +driver to utilize its resources to create a set of bidirectional queues, delivering packets between the systems. -The primary purpose of this is to be used by +The primary purpose of this driver is to be used by .Nm if_ntb network interface, but other consumers may also be developed using KPI. +.Pp +Each +.Nm +require from underlying +.Nm ntb +instance: +.Bl -bullet -compact +.It +1 or more memory windows; +.It +6 scratchpads, plus 2 more for each additional memory window; +.It +1 doorbell for each memory window or configured queue. +.El .Sh SEE ALSO .Xr if_ntb 4 , -.Xr ntb_hw 4 +.Xr ntb 4 , +.Xr ntb_hw_intel 4 , +.Xr ntb_hw_plx 4 .Sh AUTHORS .An -nosplit The .Nm driver was developed by Intel and originally written by .An Carl Delsey Aq Mt carl@FreeBSD.org . Later improvements were done by .An Conrad E. Meyer Aq Mt cem@FreeBSD.org and .An Alexander Motin Aq Mt mav@FreeBSD.org . Index: stable/11/sys/amd64/conf/NOTES =================================================================== --- stable/11/sys/amd64/conf/NOTES (revision 323452) +++ stable/11/sys/amd64/conf/NOTES (revision 323453) @@ -1,697 +1,702 @@ # # NOTES -- Lines that can be cut/pasted into kernel and hints configs. # # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. # # $FreeBSD$ # # # We want LINT to cover profiling as well. profile 2 # # Enable the kernel DTrace hooks which are required to load the DTrace # kernel modules. # options KDTRACE_HOOKS # DTrace core # NOTE: introduces CDDL-licensed components into the kernel #device dtrace # DTrace modules #device dtrace_profile #device dtrace_sdt #device dtrace_fbt #device dtrace_systrace #device dtrace_prototype #device dtnfscl #device dtmalloc # Alternatively include all the DTrace modules #device dtraceall ##################################################################### # SMP OPTIONS: # # Notes: # # IPI_PREEMPTION instructs the kernel to preempt threads running on other # CPUS if needed. Relies on the PREEMPTION option # Optional: options IPI_PREEMPTION device atpic # Optional legacy pic support device mptable # Optional MPSPEC mptable support # # Watchdog routines. # options MP_WATCHDOG # Debugging options. # options COUNT_XINVLTLB_HITS # Counters for TLB events options COUNT_IPIS # Per-CPU IPI interrupt counters ##################################################################### # CPU OPTIONS # # You must specify at least one CPU (the one you intend to run on); # deleting the specification for CPUs you don't need to use may make # parts of the system run faster. # cpu HAMMER # aka K8, aka Opteron & Athlon64 # # Options for CPU features. # # # PERFMON causes the driver for Pentium/Pentium Pro performance counters # to be compiled. See perfmon(4) for more information. # #XXX#options PERFMON ##################################################################### # NETWORKING OPTIONS # # DEVICE_POLLING adds support for mixed interrupt-polling handling # of network device drivers, which has significant benefits in terms # of robustness to overloads and responsivity, as well as permitting # accurate scheduling of the CPU time between kernel network processing # and other activities. The drawback is a moderate (up to 1/HZ seconds) # potential increase in response times. # It is strongly recommended to use HZ=1000 or 2000 with DEVICE_POLLING # to achieve smoother behaviour. # Additionally, you can enable/disable polling at runtime with help of # the ifconfig(8) utility, and select the CPU fraction reserved to # userland with the sysctl variable kern.polling.user_frac # (default 50, range 0..100). # # Not all device drivers support this mode of operation at the time of # this writing. See polling(4) for more details. options DEVICE_POLLING # BPF_JITTER adds support for BPF just-in-time compiler. options BPF_JITTER # OpenFabrics Enterprise Distribution (Infiniband). options OFED options OFED_DEBUG_INIT # Sockets Direct Protocol options SDP options SDP_DEBUG # IP over Infiniband options IPOIB options IPOIB_DEBUG options IPOIB_CM ##################################################################### # CLOCK OPTIONS # Provide read/write access to the memory in the clock chip. device nvram # Access to rtc cmos via /dev/nvram ##################################################################### # MISCELLANEOUS DEVICES AND OPTIONS device speaker #Play IBM BASIC-style noises out your speaker hint.speaker.0.at="isa" hint.speaker.0.port="0x61" device gzip #Exec gzipped a.out's. REQUIRES COMPAT_AOUT! ##################################################################### # HARDWARE BUS CONFIGURATION # # ISA bus # device isa # # Options for `isa': # # AUTO_EOI_1 enables the `automatic EOI' feature for the master 8259A # interrupt controller. This saves about 0.7-1.25 usec for each interrupt. # This option breaks suspend/resume on some portables. # # AUTO_EOI_2 enables the `automatic EOI' feature for the slave 8259A # interrupt controller. This saves about 0.7-1.25 usec for each interrupt. # Automatic EOI is documented not to work for for the slave with the # original i8259A, but it works for some clones and some integrated # versions. # # MAXMEM specifies the amount of RAM on the machine; if this is not # specified, FreeBSD will first read the amount of memory from the CMOS # RAM, so the amount of memory will initially be limited to 64MB or 16MB # depending on the BIOS. If the BIOS reports 64MB, a memory probe will # then attempt to detect the installed amount of RAM. If this probe # fails to detect >64MB RAM you will have to use the MAXMEM option. # The amount is in kilobytes, so for a machine with 128MB of RAM, it would # be 131072 (128 * 1024). # # BROKEN_KEYBOARD_RESET disables the use of the keyboard controller to # reset the CPU for reboot. This is needed on some systems with broken # keyboard controllers. options AUTO_EOI_1 #options AUTO_EOI_2 options MAXMEM=(128*1024) #options BROKEN_KEYBOARD_RESET # # AGP GART support device agp # # AGP debugging. # options AGP_DEBUG ##################################################################### # HARDWARE DEVICE CONFIGURATION # To include support for VGA VESA video modes options VESA # Turn on extra debugging checks and output for VESA support. options VESA_DEBUG device dpms # DPMS suspend & resume via VESA BIOS # x86 real mode BIOS emulator, required by atkbdc/dpms/vesa options X86BIOS # # Optional devices: # # PS/2 mouse device psm hint.psm.0.at="atkbdc" hint.psm.0.irq="12" # Options for psm: options PSM_HOOKRESUME #hook the system resume event, useful #for some laptops options PSM_RESETAFTERSUSPEND #reset the device at the resume event # The keyboard controller; it controls the keyboard and the PS/2 mouse. device atkbdc hint.atkbdc.0.at="isa" hint.atkbdc.0.port="0x060" # The AT keyboard device atkbd hint.atkbd.0.at="atkbdc" hint.atkbd.0.irq="1" # Options for atkbd: options ATKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions ATKBD_DFLT_KEYMAP=fr.dvorak # `flags' for atkbd: # 0x01 Force detection of keyboard, else we always assume a keyboard # 0x02 Don't reset keyboard, useful for some newer ThinkPads # 0x03 Force detection and avoid reset, might help with certain # dockingstations # 0x04 Old-style (XT) keyboard support, useful for older ThinkPads # Video card driver for VGA adapters. device vga hint.vga.0.at="isa" # Options for vga: # Try the following option if the mouse pointer is not drawn correctly # or font does not seem to be loaded properly. May cause flicker on # some systems. options VGA_ALT_SEQACCESS # If you can dispense with some vga driver features, you may want to # use the following options to save some memory. #options VGA_NO_FONT_LOADING # don't save/load font #options VGA_NO_MODE_CHANGE # don't change video modes # Older video cards may require this option for proper operation. options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs # The following option probably won't work with the LCD displays. options VGA_WIDTH90 # support 90 column modes # Debugging. options VGA_DEBUG # vt(4) drivers. device vt_vga # VGA device vt_efifb # EFI framebuffer # Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA. device s3pci # 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create # the /dev/3dfx0 device to work with glide implementations. This should get # linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as # the tdfx DRI module from XFree86 and is completely unrelated. # # To enable Linuxulator support, one must also include COMPAT_LINUX in the # config as well. The other option is to load both as modules. device tdfx # Enable 3Dfx Voodoo support #XXX#device tdfx_linux # Enable Linuxulator support # # ACPI support using the Intel ACPI Component Architecture reference # implementation. # # ACPI_DEBUG enables the use of the debug.acpi.level and debug.acpi.layer # kernel environment variables to select initial debugging levels for the # Intel ACPICA code. (Note that the Intel code must also have USE_DEBUGGER # defined when it is built). device acpi options ACPI_DEBUG # The cpufreq(4) driver provides support for non-ACPI CPU frequency control device cpufreq # Direct Rendering modules for 3D acceleration. device drm # DRM core module required by DRM drivers device i915drm # Intel i830 through i915 device mach64drm # ATI Rage Pro, Rage Mobility P/M, Rage XL device mgadrm # AGP Matrox G200, G400, G450, G550 device r128drm # ATI Rage 128 device radeondrm # ATI Radeon device savagedrm # S3 Savage3D, Savage4 device sisdrm # SiS 300/305, 540, 630 device tdfxdrm # 3dfx Voodoo 3/4/5 and Banshee device viadrm # VIA options DRM_DEBUG # Include debug printfs (slow) # # Network interfaces: # # bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet # adapters. # ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503 # HP PC Lan+, various PC Card devices # (requires miibus) # ipw: Intel PRO/Wireless 2100 IEEE 802.11 adapter # Requires the ipw firmware module # iwi: Intel PRO/Wireless 2200BG/2225BG/2915ABG IEEE 802.11 adapters # Requires the iwi firmware module # iwn: Intel Wireless WiFi Link 1000/105/135/2000/4965/5000/6000/6050 abgn # 802.11 network adapters # Requires the iwn firmware module # ixl: Intel XL710 40Gbe PCIE Ethernet # ixlv: Intel XL710 40Gbe VF PCIE Ethernet # mlx4ib: Mellanox ConnectX HCA InfiniBand # mlxen: Mellanox ConnectX HCA Ethernet # mthca: Mellanox HCA InfiniBand # nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source) # sfxge: Solarflare SFC9000 family 10Gb Ethernet adapters # vmx: VMware VMXNET3 Ethernet (BSD open source) # wpi: Intel 3945ABG Wireless LAN controller # Requires the wpi firmware module device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE device ed # NE[12]000, SMC Ultra, 3c503, DS8390 cards options ED_3C503 options ED_HPP options ED_SIC device ipw # Intel 2100 wireless NICs. device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs. device iwn # Intel 4965/1000/5000/6000 wireless NICs. device ixl # Intel XL710 40Gbe PCIE Ethernet options IXL_IW # Enable iWARP Client Interface in ixl(4) device ixlv # Intel XL710 40Gbe VF PCIE Ethernet device mlx4ib # Mellanox ConnectX HCA InfiniBand device mlxen # Mellanox ConnectX HCA Ethernet device mthca # Mellanox HCA InfiniBand device nfe # nVidia nForce MCP on-board Ethernet device sfxge # Solarflare SFC9000 10Gb Ethernet device vmx # VMware VMXNET3 Ethernet device wpi # Intel 3945ABG wireless NICs. # IEEE 802.11 adapter firmware modules # Intel PRO/Wireless 2100 firmware: # ipwfw: BSS/IBSS/monitor mode firmware # ipwbssfw: BSS mode firmware # ipwibssfw: IBSS mode firmware # ipwmonitorfw: Monitor mode firmware # Intel PRO/Wireless 2200BG/2225BG/2915ABG firmware: # iwifw: BSS/IBSS/monitor mode firmware # iwibssfw: BSS mode firmware # iwiibssfw: IBSS mode firmware # iwimonitorfw: Monitor mode firmware # Intel Wireless WiFi Link 4965/1000/5000/6000 series firmware: # iwnfw: Single module to support all devices # iwn1000fw: Specific module for the 1000 only # iwn105fw: Specific module for the 105 only # iwn135fw: Specific module for the 135 only # iwn2000fw: Specific module for the 2000 only # iwn2030fw: Specific module for the 2030 only # iwn4965fw: Specific module for the 4965 only # iwn5000fw: Specific module for the 5000 only # iwn5150fw: Specific module for the 5150 only # iwn6000fw: Specific module for the 6000 only # iwn6000g2afw: Specific module for the 6000g2a only # iwn6000g2bfw: Specific module for the 6000g2b only # iwn6050fw: Specific module for the 6050 only # wpifw: Intel 3945ABG Wireless LAN Controller firmware device iwifw device iwibssfw device iwiibssfw device iwimonitorfw device ipwfw device ipwbssfw device ipwibssfw device ipwmonitorfw device iwnfw device iwn1000fw device iwn105fw device iwn135fw device iwn2000fw device iwn2030fw device iwn4965fw device iwn5000fw device iwn5150fw device iwn6000fw device iwn6000g2afw device iwn6000g2bfw device iwn6050fw device wpifw -# Intel Non-Transparent Bridge (NTB) hardware -device ntb_hw # Hardware Abstraction Layer for the NTB -device if_ntb # Simulated ethernet device using the NTB +# +# Non-Transparent Bridge (NTB) drivers +# +device if_ntb # Virtual NTB network interface +device ntb_transport # NTB packet transport driver +device ntb # NTB hardware interface +device ntb_hw_intel # Intel NTB hardware driver +device ntb_hw_plx # PLX NTB hardware driver # #XXX this stores pointers in a 32bit field that is defined by the hardware #device pst # # Areca 11xx and 12xx series of SATA II RAID controllers. # CAM is required. # device arcmsr # Areca SATA II RAID # # 3ware 9000 series PATA/SATA RAID controller driver and options. # The driver is implemented as a SIM, and so, needs the CAM infrastructure. # options TWA_DEBUG # 0-10; 10 prints the most messages. options TWA_FLASH_FIRMWARE # firmware image bundled when defined. device twa # 3ware 9000 series PATA/SATA RAID # # SCSI host adapters: # # ncv: NCR 53C500 based SCSI host adapters. # nsp: Workbit Ninja SCSI-3 based PC Card SCSI host adapters. # stg: TMC 18C30, 18C50 based SCSI host adapters. device ncv device nsp device stg # # Adaptec FSA RAID controllers, including integrated DELL controllers, # the Dell PERC 2/QC and the HP NetRAID-4M device aac device aacp # SCSI Passthrough interface (optional, CAM required) # # Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming families device aacraid # Container interface, CAM required # # Highpoint RocketRAID 27xx. device hpt27xx # # Highpoint RocketRAID 182x. device hptmv # # Highpoint DC7280 and R750. device hptnr # # Highpoint RocketRAID. Supports RR172x, RR222x, RR2240, RR232x, RR2340, # RR2210, RR174x, RR2522, RR231x, RR230x. device hptrr # # Highpoint RocketRaid 3xxx series SATA RAID device hptiop # # IBM (now Adaptec) ServeRAID controllers device ips # # Intel C600 (Patsburg) integrated SAS controller device isci options ISCI_LOGGING # enable debugging in isci HAL # # NVM Express (NVMe) support device nvme # base NVMe driver device nvd # expose NVMe namespaces as disks, depends on nvme # # PMC-Sierra SAS/SATA controller device pmspcv # # SafeNet crypto driver: can be moved to the MI NOTES as soon as # it's tested on a big-endian machine # device safe # SafeNet 1141 options SAFE_DEBUG # enable debugging support: hw.safe.debug options SAFE_RNDTEST # enable rndtest support # # VirtIO support # # The virtio entry provides a generic bus for use by the device drivers. # It must be combined with an interface that communicates with the host. # Multiple such interfaces are defined by the VirtIO specification. FreeBSD # only has support for PCI. Therefore, virtio_pci must be statically # compiled in or loaded as a module for the device drivers to function. # device virtio # Generic VirtIO bus (required) device virtio_pci # VirtIO PCI Interface device vtnet # VirtIO Ethernet device device virtio_blk # VirtIO Block device device virtio_scsi # VirtIO SCSI device device virtio_balloon # VirtIO Memory Balloon device device virtio_random # VirtIO Entropy device device virtio_console # VirtIO Console device # Microsoft Hyper-V enhancement support device hyperv # HyperV drivers # Xen HVM Guest Optimizations options XENHVM # Xen HVM kernel infrastructure device xenpci # Xen HVM Hypervisor services driver ##################################################################### # # Miscellaneous hardware: # # ipmi: Intelligent Platform Management Interface # pbio: Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724) # smbios: DMI/SMBIOS entry point # vpd: Vital Product Data kernel interface # asmc: Apple System Management Controller # si: Specialix International SI/XIO or SX intelligent serial card # tpm: Trusted Platform Module # Notes on the Specialix SI/XIO driver: # The host card is memory, not IO mapped. # The Rev 1 host cards use a 64K chunk, on a 32K boundary. # The Rev 2 host cards use a 32K chunk, on a 32K boundary. # The cards can use an IRQ of 11, 12 or 15. device ipmi device pbio hint.pbio.0.at="isa" hint.pbio.0.port="0x360" device smbios device vpd device asmc device si device tpm device padlock_rng # VIA Padlock RNG device rdrand_rng # Intel Bull Mountain RNG device aesni # AES-NI OpenCrypto module device ioat # Intel I/OAT DMA engine # # Laptop/Notebook options: # # # I2C Bus # # # Hardware watchdog timers: # # ichwd: Intel ICH watchdog timer # amdsbwd: AMD SB7xx watchdog timer # viawd: VIA south bridge watchdog timer # wbwd: Winbond watchdog timer # device ichwd device amdsbwd device viawd device wbwd # # Temperature sensors: # # coretemp: on-die sensor on Intel Core and newer CPUs # amdtemp: on-die sensor on AMD K8/K10/K11 CPUs # device coretemp device amdtemp # # CPU control pseudo-device. Provides access to MSRs, CPUID info and # microcode update feature. # device cpuctl # # System Management Bus (SMB) # options ENABLE_ALART # Control alarm on Intel intpm driver # # Number of initial kernel page table pages used for early bootstrap. # This number should include enough pages to map the kernel and any # modules or other data loaded with the kernel by the loader. Each # page table page maps 2MB. # options NKPT=31 # EFI Runtime Services support (not functional yet). options EFIRT ##################################################################### # ABI Emulation #XXX keep these here for now and reactivate when support for emulating #XXX these 32 bit binaries is added. # Enable 32-bit runtime support for FreeBSD/i386 binaries. options COMPAT_FREEBSD32 # Enable iBCS2 runtime support for SCO and ISC binaries #XXX#options IBCS2 # Emulate spx device for client side of SVR3 local X interface #XXX#options SPX_HACK # Enable 32-bit runtime support for CloudABI binaries. options COMPAT_CLOUDABI32 # Enable 64-bit runtime support for CloudABI binaries. options COMPAT_CLOUDABI64 # Enable Linux ABI emulation #XXX#options COMPAT_LINUX # Enable 32-bit Linux ABI emulation (requires COMPAT_43 and COMPAT_FREEBSD32) options COMPAT_LINUX32 # Enable the linux-like proc filesystem support (requires COMPAT_LINUX32 # and PSEUDOFS) options LINPROCFS #Enable the linux-like sys filesystem support (requires COMPAT_LINUX32 # and PSEUDOFS) options LINSYSFS # # SysVR4 ABI emulation # # The svr4 ABI emulator can be statically compiled into the kernel or loaded as # a KLD module. # The STREAMS network emulation code can also be compiled statically or as a # module. If loaded as a module, it must be loaded before the svr4 module # (the /usr/sbin/svr4 script does this for you). If compiling statically, # the `streams' device must be configured into any kernel which also # specifies COMPAT_SVR4. It is possible to have a statically-configured # STREAMS device and a dynamically loadable svr4 emulator; the /usr/sbin/svr4 # script understands that it doesn't need to load the `streams' module under # those circumstances. # Caveat: At this time, `options KTRACE' is required for the svr4 emulator # (whether static or dynamic). # #XXX#options COMPAT_SVR4 # build emulator statically #XXX#options DEBUG_SVR4 # enable verbose debugging #XXX#device streams # STREAMS network driver (required for svr4). ##################################################################### # VM OPTIONS # KSTACK_PAGES is the number of memory pages to assign to the kernel # stack of each thread. options KSTACK_PAGES=5 # Enable detailed accounting by the PV entry allocator. options PV_STATS ##################################################################### # More undocumented options for linting. # Note that documenting these are not considered an affront. options FB_INSTALL_CDEV # install a CDEV entry in /dev options KBDIO_DEBUG=2 options KBD_MAXRETRY=4 options KBD_MAXWAIT=6 options KBD_RESETDELAY=201 options PSM_DEBUG=1 options TIMER_FREQ=((14318182+6)/12) options VM_KMEM_SIZE options VM_KMEM_SIZE_MAX options VM_KMEM_SIZE_SCALE # Enable NDIS binary driver support options NDISAPI device ndis Index: stable/11/sys/conf/files.amd64 =================================================================== --- stable/11/sys/conf/files.amd64 (revision 323452) +++ stable/11/sys/conf/files.amd64 (revision 323453) @@ -1,695 +1,696 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # # cloudabi32_vdso.o optional compat_cloudabi32 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S" \ compile-with "${CC} -x assembler-with-cpp -m32 -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_i686_on_64bit.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi32_vdso.o" # cloudabi32_vdso_blob.o optional compat_cloudabi32 \ dependency "cloudabi32_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 cloudabi32_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi32_vdso_blob.o" # cloudabi64_vdso.o optional compat_cloudabi64 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_x86_64.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_x86_64.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi64_vdso.o" # cloudabi64_vdso_blob.o optional compat_cloudabi64 \ dependency "cloudabi64_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 cloudabi64_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi64_vdso_blob.o" # linux32_genassym.o optional compat_linux32 \ dependency "$S/amd64/linux32/linux32_genassym.c" \ compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "linux32_genassym.o" # linux32_assym.h optional compat_linux32 \ dependency "$S/kern/genassym.sh linux32_genassym.o" \ compile-with "sh $S/kern/genassym.sh linux32_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "linux32_assym.h" # linux32_locore.o optional compat_linux32 \ dependency "linux32_assym.h $S/amd64/linux32/linux32_locore.s" \ compile-with "${CC} -x assembler-with-cpp -DLOCORE -m32 -shared -s -pipe -I. -I$S -Werror -Wall -fPIC -fno-common -nostdinc -nostdlib -Wl,-T$S/amd64/linux32/linux32_vdso.lds.s -Wl,-soname=linux32_vdso.so,--eh-frame-hdr,-warn-common ${.IMPSRC} -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "linux32_locore.o" # linux32_vdso.so optional compat_linux32 \ dependency "linux32_locore.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd --binary-architecture i386 linux32_locore.o ${.TARGET}" \ no-implicit-rule \ clean "linux32_vdso.so" # ia32_genassym.o standard \ dependency "$S/compat/ia32/ia32_genassym.c" \ compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "ia32_genassym.o" # ia32_assym.h standard \ dependency "$S/kern/genassym.sh ia32_genassym.o" \ compile-with "env NM='${NM}' NMFLAGS='${NMFLAGS}' sh $S/kern/genassym.sh ia32_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "ia32_assym.h" # font.h optional sc_dflt_font \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "atkbdmap.h" # ukbdmap.h optional ukbd_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # hpt27xx_lib.o optional hpt27xx \ dependency "$S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \ compile-with "uudecode < $S/dev/hpt27xx/amd64-elf.hpt27xx_lib.o.uu" \ no-implicit-rule # hptmvraid.o optional hptmv \ dependency "$S/dev/hptmv/amd64-elf.raid.o.uu" \ compile-with "uudecode < $S/dev/hptmv/amd64-elf.raid.o.uu" \ no-implicit-rule # hptnr_lib.o optional hptnr \ dependency "$S/dev/hptnr/amd64-elf.hptnr_lib.o.uu" \ compile-with "uudecode < $S/dev/hptnr/amd64-elf.hptnr_lib.o.uu" \ no-implicit-rule # hptrr_lib.o optional hptrr \ dependency "$S/dev/hptrr/amd64-elf.hptrr_lib.o.uu" \ compile-with "uudecode < $S/dev/hptrr/amd64-elf.hptrr_lib.o.uu" \ no-implicit-rule # amd64/acpica/acpi_machdep.c optional acpi acpi_wakecode.o optional acpi \ dependency "$S/amd64/acpica/acpi_wakecode.S assym.s" \ compile-with "${NORMAL_S}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.o" acpi_wakecode.bin optional acpi \ dependency "acpi_wakecode.o" \ compile-with "${OBJCOPY} -S -O binary acpi_wakecode.o ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.bin" acpi_wakecode.h optional acpi \ dependency "acpi_wakecode.bin" \ compile-with "file2c -sx 'static char wakecode[] = {' '};' < acpi_wakecode.bin > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.h" acpi_wakedata.h optional acpi \ dependency "acpi_wakecode.o" \ compile-with '${NM} -n --defined-only acpi_wakecode.o | while read offset dummy what; do echo "#define $${what} 0x$${offset}"; done > ${.TARGET}' \ no-obj no-implicit-rule before-depend \ clean "acpi_wakedata.h" # #amd64/amd64/apic_vector.S standard amd64/amd64/atomic.c standard amd64/amd64/bios.c standard amd64/amd64/bpf_jit_machdep.c optional bpf_jitter amd64/amd64/cpu_switch.S standard amd64/amd64/db_disasm.c optional ddb amd64/amd64/db_interface.c optional ddb amd64/amd64/db_trace.c optional ddb amd64/amd64/efirt.c optional efirt amd64/amd64/elf_machdep.c standard amd64/amd64/exception.S standard amd64/amd64/fpu.c standard amd64/amd64/gdb_machdep.c optional gdb amd64/amd64/in_cksum.c optional inet | inet6 amd64/amd64/initcpu.c standard amd64/amd64/io.c optional io amd64/amd64/locore.S standard no-obj amd64/amd64/xen-locore.S optional xenhvm amd64/amd64/machdep.c standard amd64/amd64/mem.c optional mem amd64/amd64/minidump_machdep.c standard amd64/amd64/mp_machdep.c optional smp amd64/amd64/mpboot.S optional smp amd64/amd64/pmap.c standard amd64/amd64/prof_machdep.c optional profiling-routine amd64/amd64/ptrace_machdep.c standard amd64/amd64/sigtramp.S standard amd64/amd64/support.S standard amd64/amd64/sys_machdep.c standard amd64/amd64/trap.c standard amd64/amd64/uio_machdep.c standard amd64/amd64/uma_machdep.c standard amd64/amd64/vm_machdep.c standard amd64/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 amd64/cloudabi64/cloudabi64_sysvec.c optional compat_cloudabi64 amd64/pci/pci_cfgreg.c optional pci cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}" cddl/dev/dtrace/amd64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/amd64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}" cddl/dev/dtrace/amd64/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}" crypto/aesni/aeskeys_amd64.S optional aesni crypto/aesni/aesni.c optional aesni aesni_ghash.o optional aesni \ dependency "$S/crypto/aesni/aesni_ghash.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes -mpclmul ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_ghash.o" aesni_wrap.o optional aesni \ dependency "$S/crypto/aesni/aesni_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_wrap.o" crypto/blowfish/bf_enc.c optional crypto | ipsec | ipsec_support crypto/des/des_enc.c optional crypto | ipsec | \ ipsec_support | netsmb crypto/via/padlock.c optional padlock crypto/via/padlock_cipher.c optional padlock crypto/via/padlock_hash.c optional padlock dev/acpica/acpi_if.m standard dev/acpica/acpi_hpet.c optional acpi dev/acpi_support/acpi_wmi_if.m standard dev/agp/agp_amd64.c optional agp dev/agp/agp_i810.c optional agp dev/agp/agp_via.c optional agp dev/amdsbwd/amdsbwd.c optional amdsbwd dev/amdtemp/amdtemp.c optional amdtemp dev/arcmsr/arcmsr.c optional arcmsr pci dev/asmc/asmc.c optional asmc isa dev/atkbdc/atkbd.c optional atkbd atkbdc dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc dev/atkbdc/atkbdc.c optional atkbdc dev/atkbdc/atkbdc_isa.c optional atkbdc isa dev/atkbdc/atkbdc_subr.c optional atkbdc dev/atkbdc/psm.c optional psm atkbdc dev/bxe/bxe.c optional bxe pci dev/bxe/bxe_stats.c optional bxe pci dev/bxe/bxe_debug.c optional bxe pci dev/bxe/ecore_sp.c optional bxe pci dev/bxe/bxe_elink.c optional bxe pci dev/bxe/57710_init_values.c optional bxe pci dev/bxe/57711_init_values.c optional bxe pci dev/bxe/57712_init_values.c optional bxe pci dev/coretemp/coretemp.c optional coretemp dev/cpuctl/cpuctl.c optional cpuctl dev/dpms/dpms.c optional dpms # There are no systems with isa slots, so all ed isa entries should go.. dev/ed/if_ed_3c503.c optional ed isa ed_3c503 dev/ed/if_ed_isa.c optional ed isa dev/ed/if_ed_wd80x3.c optional ed isa dev/ed/if_ed_hpp.c optional ed isa ed_hpp dev/ed/if_ed_sic.c optional ed isa ed_sic dev/fb/fb.c optional fb | vga dev/fb/s3_pci.c optional s3pci dev/fb/vesa.c optional vga vesa dev/fb/vga.c optional vga dev/ichwd/ichwd.c optional ichwd dev/if_ndis/if_ndis.c optional ndis dev/if_ndis/if_ndis_pccard.c optional ndis pccard dev/if_ndis/if_ndis_pci.c optional ndis cardbus | ndis pci dev/if_ndis/if_ndis_usb.c optional ndis usb dev/intel/spi.c optional intelspi dev/io/iodev.c optional io dev/ioat/ioat.c optional ioat pci dev/ioat/ioat_test.c optional ioat pci dev/ipmi/ipmi.c optional ipmi dev/ipmi/ipmi_acpi.c optional ipmi acpi dev/ipmi/ipmi_isa.c optional ipmi isa dev/ipmi/ipmi_kcs.c optional ipmi dev/ipmi/ipmi_smic.c optional ipmi dev/ipmi/ipmi_smbus.c optional ipmi smbus dev/ipmi/ipmi_smbios.c optional ipmi dev/ipmi/ipmi_ssif.c optional ipmi smbus dev/ipmi/ipmi_pci.c optional ipmi pci dev/ipmi/ipmi_linux.c optional ipmi compat_linux32 dev/ixl/if_ixl.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_main.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_qmgr.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_iov.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_pf_i2c.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_iw.c optional ixl pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/if_ixlv.c optional ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixlvc.c optional ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/ixl_txrx.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_osdep.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_lan_hmc.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_hmc.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_common.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_nvm.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/ixl/i40e_adminq.c optional ixl pci | ixlv pci \ compile-with "${NORMAL_C} -I$S/dev/ixl" dev/fdc/fdc.c optional fdc dev/fdc/fdc_acpi.c optional fdc dev/fdc/fdc_isa.c optional fdc isa dev/fdc/fdc_pccard.c optional fdc pccard dev/gpio/bytgpio.c optional bytgpio dev/hpt27xx/hpt27xx_os_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_osm_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_config.c optional hpt27xx dev/hptmv/entry.c optional hptmv dev/hptmv/mv.c optional hptmv dev/hptmv/gui_lib.c optional hptmv dev/hptmv/hptproc.c optional hptmv dev/hptmv/ioctl.c optional hptmv dev/hptnr/hptnr_os_bsd.c optional hptnr dev/hptnr/hptnr_osm_bsd.c optional hptnr dev/hptnr/hptnr_config.c optional hptnr dev/hptrr/hptrr_os_bsd.c optional hptrr dev/hptrr/hptrr_osm_bsd.c optional hptrr dev/hptrr/hptrr_config.c optional hptrr dev/hwpmc/hwpmc_amd.c optional hwpmc dev/hwpmc/hwpmc_intel.c optional hwpmc dev/hwpmc/hwpmc_core.c optional hwpmc dev/hwpmc/hwpmc_uncore.c optional hwpmc dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/input/hv_kbd.c optional hyperv dev/hyperv/input/hv_kbdc.c optional hyperv dev/hyperv/pcib/vmbus_pcib.c optional hyperv pci dev/hyperv/netvsc/hn_nvs.c optional hyperv dev/hyperv/netvsc/hn_rndis.c optional hyperv dev/hyperv/netvsc/if_hn.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv dev/hyperv/utilities/hv_snapshot.c optional hyperv dev/hyperv/utilities/vmbus_heartbeat.c optional hyperv dev/hyperv/utilities/vmbus_ic.c optional hyperv dev/hyperv/utilities/vmbus_shutdown.c optional hyperv dev/hyperv/utilities/vmbus_timesync.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv pci dev/hyperv/vmbus/vmbus_br.c optional hyperv dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/vmbus_res.c optional hyperv dev/hyperv/vmbus/vmbus_xact.c optional hyperv dev/hyperv/vmbus/amd64/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/amd64/vmbus_vector.S optional hyperv dev/nctgpio/nctgpio.c optional nctgpio dev/nfe/if_nfe.c optional nfe pci dev/ntb/if_ntb/if_ntb.c optional if_ntb -dev/ntb/ntb_transport.c optional if_ntb -dev/ntb/ntb.c optional if_ntb | ntb_hw -dev/ntb/ntb_if.m optional if_ntb | ntb_hw -dev/ntb/ntb_hw/ntb_hw.c optional ntb_hw +dev/ntb/ntb_transport.c optional ntb_transport | if_ntb +dev/ntb/ntb.c optional ntb | ntb_transport | if_ntb | ntb_hw_intel | ntb_hw_plx | ntb_hw +dev/ntb/ntb_if.m optional ntb | ntb_transport | if_ntb | ntb_hw_intel | ntb_hw_plx | ntb_hw +dev/ntb/ntb_hw/ntb_hw_intel.c optional ntb_hw_intel | ntb_hw +dev/ntb/ntb_hw/ntb_hw_plx.c optional ntb_hw_plx | ntb_hw dev/nvd/nvd.c optional nvd nvme dev/nvme/nvme.c optional nvme dev/nvme/nvme_ctrlr.c optional nvme dev/nvme/nvme_ctrlr_cmd.c optional nvme dev/nvme/nvme_ns.c optional nvme dev/nvme/nvme_ns_cmd.c optional nvme dev/nvme/nvme_qpair.c optional nvme dev/nvme/nvme_sim.c optional nvme scbus !nvd dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/nvram/nvram.c optional nvram isa dev/random/ivy.c optional rdrand_rng dev/random/nehemiah.c optional padlock_rng dev/qlxge/qls_dbg.c optional qlxge pci dev/qlxge/qls_dump.c optional qlxge pci dev/qlxge/qls_hw.c optional qlxge pci dev/qlxge/qls_ioctl.c optional qlxge pci dev/qlxge/qls_isr.c optional qlxge pci dev/qlxge/qls_os.c optional qlxge pci dev/qlxgb/qla_dbg.c optional qlxgb pci dev/qlxgb/qla_hw.c optional qlxgb pci dev/qlxgb/qla_ioctl.c optional qlxgb pci dev/qlxgb/qla_isr.c optional qlxgb pci dev/qlxgb/qla_misc.c optional qlxgb pci dev/qlxgb/qla_os.c optional qlxgb pci dev/qlxgbe/ql_dbg.c optional qlxgbe pci dev/qlxgbe/ql_hw.c optional qlxgbe pci dev/qlxgbe/ql_ioctl.c optional qlxgbe pci dev/qlxgbe/ql_isr.c optional qlxgbe pci dev/qlxgbe/ql_misc.c optional qlxgbe pci dev/qlxgbe/ql_os.c optional qlxgbe pci dev/qlxgbe/ql_reset.c optional qlxgbe pci dev/qlnx/qlnxe/ecore_cxt.c optional qlnxe pci dev/qlnx/qlnxe/ecore_dbg_fw_funcs.c optional qlnxe pci dev/qlnx/qlnxe/ecore_dcbx.c optional qlnxe pci dev/qlnx/qlnxe/ecore_dev.c optional qlnxe pci dev/qlnx/qlnxe/ecore_hw.c optional qlnxe pci dev/qlnx/qlnxe/ecore_init_fw_funcs.c optional qlnxe pci dev/qlnx/qlnxe/ecore_init_ops.c optional qlnxe pci dev/qlnx/qlnxe/ecore_int.c optional qlnxe pci dev/qlnx/qlnxe/ecore_l2.c optional qlnxe pci dev/qlnx/qlnxe/ecore_mcp.c optional qlnxe pci dev/qlnx/qlnxe/ecore_sp_commands.c optional qlnxe pci dev/qlnx/qlnxe/ecore_spq.c optional qlnxe pci dev/qlnx/qlnxe/qlnx_ioctl.c optional qlnxe pci dev/qlnx/qlnxe/qlnx_os.c optional qlnxe pci dev/sfxge/common/ef10_ev.c optional sfxge pci dev/sfxge/common/ef10_filter.c optional sfxge pci dev/sfxge/common/ef10_intr.c optional sfxge pci dev/sfxge/common/ef10_mac.c optional sfxge pci dev/sfxge/common/ef10_mcdi.c optional sfxge pci dev/sfxge/common/ef10_nic.c optional sfxge pci dev/sfxge/common/ef10_nvram.c optional sfxge pci dev/sfxge/common/ef10_phy.c optional sfxge pci dev/sfxge/common/ef10_rx.c optional sfxge pci dev/sfxge/common/ef10_tx.c optional sfxge pci dev/sfxge/common/ef10_vpd.c optional sfxge pci dev/sfxge/common/efx_bootcfg.c optional sfxge pci dev/sfxge/common/efx_crc32.c optional sfxge pci dev/sfxge/common/efx_ev.c optional sfxge pci dev/sfxge/common/efx_filter.c optional sfxge pci dev/sfxge/common/efx_hash.c optional sfxge pci dev/sfxge/common/efx_intr.c optional sfxge pci dev/sfxge/common/efx_lic.c optional sfxge pci dev/sfxge/common/efx_mac.c optional sfxge pci dev/sfxge/common/efx_mcdi.c optional sfxge pci dev/sfxge/common/efx_mon.c optional sfxge pci dev/sfxge/common/efx_nic.c optional sfxge pci dev/sfxge/common/efx_nvram.c optional sfxge pci dev/sfxge/common/efx_phy.c optional sfxge pci dev/sfxge/common/efx_port.c optional sfxge pci dev/sfxge/common/efx_rx.c optional sfxge pci dev/sfxge/common/efx_sram.c optional sfxge pci dev/sfxge/common/efx_tx.c optional sfxge pci dev/sfxge/common/efx_vpd.c optional sfxge pci dev/sfxge/common/hunt_nic.c optional sfxge pci dev/sfxge/common/mcdi_mon.c optional sfxge pci dev/sfxge/common/medford_nic.c optional sfxge pci dev/sfxge/common/siena_mac.c optional sfxge pci dev/sfxge/common/siena_mcdi.c optional sfxge pci dev/sfxge/common/siena_nic.c optional sfxge pci dev/sfxge/common/siena_nvram.c optional sfxge pci dev/sfxge/common/siena_phy.c optional sfxge pci dev/sfxge/common/siena_sram.c optional sfxge pci dev/sfxge/common/siena_vpd.c optional sfxge pci dev/sfxge/sfxge.c optional sfxge pci dev/sfxge/sfxge_dma.c optional sfxge pci dev/sfxge/sfxge_ev.c optional sfxge pci dev/sfxge/sfxge_intr.c optional sfxge pci dev/sfxge/sfxge_mcdi.c optional sfxge pci dev/sfxge/sfxge_nvram.c optional sfxge pci dev/sfxge/sfxge_port.c optional sfxge pci dev/sfxge/sfxge_rx.c optional sfxge pci dev/sfxge/sfxge_tx.c optional sfxge pci dev/sio/sio.c optional sio dev/sio/sio_isa.c optional sio isa dev/sio/sio_pccard.c optional sio pccard dev/sio/sio_pci.c optional sio pci dev/sio/sio_puc.c optional sio puc dev/speaker/spkr.c optional speaker dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/scterm-teken.c optional sc dev/syscons/scvesactl.c optional sc vga vesa dev/syscons/scvgarndr.c optional sc vga dev/syscons/scvtb.c optional sc dev/tpm/tpm.c optional tpm dev/tpm/tpm_acpi.c optional tpm acpi dev/tpm/tpm_isa.c optional tpm isa dev/uart/uart_cpu_x86.c optional uart dev/viawd/viawd.c optional viawd dev/vmware/vmxnet3/if_vmx.c optional vmx dev/wbwd/wbwd.c optional wbwd dev/wpi/if_wpi.c optional wpi dev/xen/pci/xen_acpi_pci.c optional xenhvm dev/xen/pci/xen_pci.c optional xenhvm dev/isci/isci.c optional isci dev/isci/isci_controller.c optional isci dev/isci/isci_domain.c optional isci dev/isci/isci_interrupt.c optional isci dev/isci/isci_io_request.c optional isci dev/isci/isci_logger.c optional isci dev/isci/isci_oem_parameters.c optional isci dev/isci/isci_remote_device.c optional isci dev/isci/isci_sysctl.c optional isci dev/isci/isci_task_request.c optional isci dev/isci/isci_timer.c optional isci dev/isci/scil/sati.c optional isci dev/isci/scil/sati_abort_task_set.c optional isci dev/isci/scil/sati_atapi.c optional isci dev/isci/scil/sati_device.c optional isci dev/isci/scil/sati_inquiry.c optional isci dev/isci/scil/sati_log_sense.c optional isci dev/isci/scil/sati_lun_reset.c optional isci dev/isci/scil/sati_mode_pages.c optional isci dev/isci/scil/sati_mode_select.c optional isci dev/isci/scil/sati_mode_sense.c optional isci dev/isci/scil/sati_mode_sense_10.c optional isci dev/isci/scil/sati_mode_sense_6.c optional isci dev/isci/scil/sati_move.c optional isci dev/isci/scil/sati_passthrough.c optional isci dev/isci/scil/sati_read.c optional isci dev/isci/scil/sati_read_buffer.c optional isci dev/isci/scil/sati_read_capacity.c optional isci dev/isci/scil/sati_reassign_blocks.c optional isci dev/isci/scil/sati_report_luns.c optional isci dev/isci/scil/sati_request_sense.c optional isci dev/isci/scil/sati_start_stop_unit.c optional isci dev/isci/scil/sati_synchronize_cache.c optional isci dev/isci/scil/sati_test_unit_ready.c optional isci dev/isci/scil/sati_unmap.c optional isci dev/isci/scil/sati_util.c optional isci dev/isci/scil/sati_verify.c optional isci dev/isci/scil/sati_write.c optional isci dev/isci/scil/sati_write_and_verify.c optional isci dev/isci/scil/sati_write_buffer.c optional isci dev/isci/scil/sati_write_long.c optional isci dev/isci/scil/sci_abstract_list.c optional isci dev/isci/scil/sci_base_controller.c optional isci dev/isci/scil/sci_base_domain.c optional isci dev/isci/scil/sci_base_iterator.c optional isci dev/isci/scil/sci_base_library.c optional isci dev/isci/scil/sci_base_logger.c optional isci dev/isci/scil/sci_base_memory_descriptor_list.c optional isci dev/isci/scil/sci_base_memory_descriptor_list_decorator.c optional isci dev/isci/scil/sci_base_object.c optional isci dev/isci/scil/sci_base_observer.c optional isci dev/isci/scil/sci_base_phy.c optional isci dev/isci/scil/sci_base_port.c optional isci dev/isci/scil/sci_base_remote_device.c optional isci dev/isci/scil/sci_base_request.c optional isci dev/isci/scil/sci_base_state_machine.c optional isci dev/isci/scil/sci_base_state_machine_logger.c optional isci dev/isci/scil/sci_base_state_machine_observer.c optional isci dev/isci/scil/sci_base_subject.c optional isci dev/isci/scil/sci_util.c optional isci dev/isci/scil/scic_sds_controller.c optional isci dev/isci/scil/scic_sds_library.c optional isci dev/isci/scil/scic_sds_pci.c optional isci dev/isci/scil/scic_sds_phy.c optional isci dev/isci/scil/scic_sds_port.c optional isci dev/isci/scil/scic_sds_port_configuration_agent.c optional isci dev/isci/scil/scic_sds_remote_device.c optional isci dev/isci/scil/scic_sds_remote_node_context.c optional isci dev/isci/scil/scic_sds_remote_node_table.c optional isci dev/isci/scil/scic_sds_request.c optional isci dev/isci/scil/scic_sds_sgpio.c optional isci dev/isci/scil/scic_sds_smp_remote_device.c optional isci dev/isci/scil/scic_sds_smp_request.c optional isci dev/isci/scil/scic_sds_ssp_request.c optional isci dev/isci/scil/scic_sds_stp_packet_request.c optional isci dev/isci/scil/scic_sds_stp_remote_device.c optional isci dev/isci/scil/scic_sds_stp_request.c optional isci dev/isci/scil/scic_sds_unsolicited_frame_control.c optional isci dev/isci/scil/scif_sas_controller.c optional isci dev/isci/scil/scif_sas_controller_state_handlers.c optional isci dev/isci/scil/scif_sas_controller_states.c optional isci dev/isci/scil/scif_sas_domain.c optional isci dev/isci/scil/scif_sas_domain_state_handlers.c optional isci dev/isci/scil/scif_sas_domain_states.c optional isci dev/isci/scil/scif_sas_high_priority_request_queue.c optional isci dev/isci/scil/scif_sas_internal_io_request.c optional isci dev/isci/scil/scif_sas_io_request.c optional isci dev/isci/scil/scif_sas_io_request_state_handlers.c optional isci dev/isci/scil/scif_sas_io_request_states.c optional isci dev/isci/scil/scif_sas_library.c optional isci dev/isci/scil/scif_sas_remote_device.c optional isci dev/isci/scil/scif_sas_remote_device_ready_substate_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_ready_substates.c optional isci dev/isci/scil/scif_sas_remote_device_starting_substate_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_starting_substates.c optional isci dev/isci/scil/scif_sas_remote_device_state_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_states.c optional isci dev/isci/scil/scif_sas_request.c optional isci dev/isci/scil/scif_sas_smp_activity_clear_affiliation.c optional isci dev/isci/scil/scif_sas_smp_io_request.c optional isci dev/isci/scil/scif_sas_smp_phy.c optional isci dev/isci/scil/scif_sas_smp_remote_device.c optional isci dev/isci/scil/scif_sas_stp_io_request.c optional isci dev/isci/scil/scif_sas_stp_remote_device.c optional isci dev/isci/scil/scif_sas_stp_task_request.c optional isci dev/isci/scil/scif_sas_task_request.c optional isci dev/isci/scil/scif_sas_task_request_state_handlers.c optional isci dev/isci/scil/scif_sas_task_request_states.c optional isci dev/isci/scil/scif_sas_timer.c optional isci isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/kern_clocksource.c standard kern/link_elf_obj.c standard libkern/x86/crc32_sse42.c standard libkern/memmove.c standard libkern/memset.c standard # # IA32 binary support # #amd64/ia32/ia32_exception.S optional compat_freebsd32 amd64/ia32/ia32_reg.c optional compat_freebsd32 amd64/ia32/ia32_signal.c optional compat_freebsd32 amd64/ia32/ia32_sigtramp.S optional compat_freebsd32 amd64/ia32/ia32_syscall.c optional compat_freebsd32 amd64/ia32/ia32_misc.c optional compat_freebsd32 compat/ia32/ia32_sysvec.c optional compat_freebsd32 compat/linprocfs/linprocfs.c optional linprocfs compat/linsysfs/linsysfs.c optional linsysfs # # Linux/i386 binary support # amd64/linux32/linux32_dummy.c optional compat_linux32 amd64/linux32/linux32_machdep.c optional compat_linux32 amd64/linux32/linux32_support.s optional compat_linux32 \ dependency "linux32_assym.h" amd64/linux32/linux32_sysent.c optional compat_linux32 amd64/linux32/linux32_sysvec.c optional compat_linux32 compat/linux/linux_emul.c optional compat_linux32 compat/linux/linux_file.c optional compat_linux32 compat/linux/linux_fork.c optional compat_linux32 compat/linux/linux_futex.c optional compat_linux32 compat/linux/linux_getcwd.c optional compat_linux32 compat/linux/linux_ioctl.c optional compat_linux32 compat/linux/linux_ipc.c optional compat_linux32 compat/linux/linux_mib.c optional compat_linux32 compat/linux/linux_misc.c optional compat_linux32 compat/linux/linux_mmap.c optional compat_linux32 compat/linux/linux_signal.c optional compat_linux32 compat/linux/linux_socket.c optional compat_linux32 compat/linux/linux_stats.c optional compat_linux32 compat/linux/linux_sysctl.c optional compat_linux32 compat/linux/linux_time.c optional compat_linux32 compat/linux/linux_timer.c optional compat_linux32 compat/linux/linux_uid16.c optional compat_linux32 compat/linux/linux_util.c optional compat_linux32 compat/linux/linux_vdso.c optional compat_linux32 compat/linux/linux_common.c optional compat_linux32 compat/linux/linux_event.c optional compat_linux32 compat/linux/linux.c optional compat_linux32 dev/amr/amr_linux.c optional compat_linux32 amr dev/mfi/mfi_linux.c optional compat_linux32 mfi # # Windows NDIS driver support # compat/ndis/kern_ndis.c optional ndisapi pci compat/ndis/kern_windrv.c optional ndisapi pci compat/ndis/subr_hal.c optional ndisapi pci compat/ndis/subr_ndis.c optional ndisapi pci compat/ndis/subr_ntoskrnl.c optional ndisapi pci compat/ndis/subr_pe.c optional ndisapi pci compat/ndis/subr_usbd.c optional ndisapi pci compat/ndis/winx64_wrap.S optional ndisapi pci # # x86 real mode BIOS emulator, required by dpms/pci/vesa # compat/x86bios/x86bios.c optional x86bios | dpms | pci | vesa contrib/x86emu/x86emu.c optional x86bios | dpms | pci | vesa # # bvm console # dev/bvm/bvm_console.c optional bvmconsole dev/bvm/bvm_dbg.c optional bvmdebug # # x86 shared code between IA32, AMD64 and PC98 architectures # x86/acpica/OsdEnvironment.c optional acpi x86/acpica/acpi_apm.c optional acpi x86/acpica/acpi_wakeup.c optional acpi x86/acpica/madt.c optional acpi x86/acpica/srat.c optional acpi x86/bios/smbios.c optional smbios x86/bios/vpd.c optional vpd x86/cpufreq/powernow.c optional cpufreq x86/cpufreq/est.c optional cpufreq x86/cpufreq/hwpstate.c optional cpufreq x86/cpufreq/p4tcc.c optional cpufreq x86/iommu/busdma_dmar.c optional acpi acpi_dmar pci x86/iommu/intel_ctx.c optional acpi acpi_dmar pci x86/iommu/intel_drv.c optional acpi acpi_dmar pci x86/iommu/intel_fault.c optional acpi acpi_dmar pci x86/iommu/intel_gas.c optional acpi acpi_dmar pci x86/iommu/intel_idpgtbl.c optional acpi acpi_dmar pci x86/iommu/intel_intrmap.c optional acpi acpi_dmar pci x86/iommu/intel_qi.c optional acpi acpi_dmar pci x86/iommu/intel_quirks.c optional acpi acpi_dmar pci x86/iommu/intel_utils.c optional acpi acpi_dmar pci x86/isa/atpic.c optional atpic isa x86/isa/atrtc.c standard x86/isa/clock.c standard x86/isa/elcr.c optional atpic isa | mptable x86/isa/isa.c standard x86/isa/isa_dma.c standard x86/isa/nmi.c standard x86/isa/orm.c optional isa x86/pci/pci_bus.c optional pci x86/pci/qpi.c optional pci x86/x86/autoconf.c standard x86/x86/bus_machdep.c standard x86/x86/busdma_bounce.c standard x86/x86/busdma_machdep.c standard x86/x86/cpu_machdep.c standard x86/x86/dump_machdep.c standard x86/x86/fdt_machdep.c optional fdt x86/x86/identcpu.c standard x86/x86/intr_machdep.c standard x86/x86/io_apic.c standard x86/x86/legacy.c standard x86/x86/local_apic.c standard x86/x86/mca.c standard x86/x86/x86_mem.c optional mem x86/x86/mptable.c optional mptable x86/x86/mptable_pci.c optional mptable pci x86/x86/mp_x86.c optional smp x86/x86/mp_watchdog.c optional mp_watchdog smp x86/x86/msi.c optional pci x86/x86/nexus.c standard x86/x86/pvclock.c standard x86/x86/stack_machdep.c optional ddb | stack x86/x86/tsc.c standard x86/x86/delay.c standard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xenhvm x86/xen/pv.c optional xenhvm x86/xen/pvcpu_enum.c optional xenhvm x86/xen/xen_apic.c optional xenhvm x86/xen/xenpv.c optional xenhvm x86/xen/xen_nexus.c optional xenhvm x86/xen/xen_msi.c optional xenhvm x86/xen/xen_pci_bus.c optional xenhvm Index: stable/11/sys/conf/files.i386 =================================================================== --- stable/11/sys/conf/files.i386 (revision 323452) +++ stable/11/sys/conf/files.i386 (revision 323453) @@ -1,646 +1,647 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # cloudabi32_vdso.o optional compat_cloudabi32 \ dependency "$S/contrib/cloudabi/cloudabi_vdso_i686.S" \ compile-with "${CC} -x assembler-with-cpp -shared -nostdinc -nostdlib -Wl,-T$S/compat/cloudabi/cloudabi_vdso.lds $S/contrib/cloudabi/cloudabi_vdso_i686.S -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "cloudabi32_vdso.o" # cloudabi32_vdso_blob.o optional compat_cloudabi32 \ dependency "cloudabi32_vdso.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd --binary-architecture i386 cloudabi32_vdso.o ${.TARGET}" \ no-implicit-rule \ clean "cloudabi32_vdso_blob.o" # linux_genassym.o optional compat_linux \ dependency "$S/i386/linux/linux_genassym.c" \ compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "linux_genassym.o" # linux_assym.h optional compat_linux \ dependency "$S/kern/genassym.sh linux_genassym.o" \ compile-with "sh $S/kern/genassym.sh linux_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "linux_assym.h" # linux_locore.o optional compat_linux \ dependency "linux_assym.h $S/i386/linux/linux_locore.s" \ compile-with "${CC} -x assembler-with-cpp -DLOCORE -shared -s -pipe -I. -I$S -Werror -Wall -fPIC -fno-common -nostdinc -nostdlib -Wl,-T$S/i386/linux/linux_vdso.lds.s -Wl,-soname=linux_vdso.so,--eh-frame-hdr,-warn-common ${.IMPSRC} -o ${.TARGET}" \ no-obj no-implicit-rule \ clean "linux_locore.o" # linux_vdso.so optional compat_linux \ dependency "linux_locore.o" \ compile-with "${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd --binary-architecture i386 linux_locore.o ${.TARGET}" \ no-implicit-rule \ clean "linux_vdso.so" # svr4_genassym.o optional compat_svr4 \ dependency "$S/i386/svr4/svr4_genassym.c" \ compile-with "${CC} ${CFLAGS:N-flto:N-fno-common} -c ${.IMPSRC}" \ no-obj no-implicit-rule \ clean "svr4_genassym.o" # svr4_assym.h optional compat_svr4 \ dependency "$S/kern/genassym.sh svr4_genassym.o" \ compile-with "sh $S/kern/genassym.sh svr4_genassym.o > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "svr4_assym.h" # font.h optional sc_dflt_font \ compile-with "uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x16.fnt && file2c 'static u_char dflt_font_16[16*256] = {' '};' < ${SC_DFLT_FONT}-8x16 > font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x14.fnt && file2c 'static u_char dflt_font_14[14*256] = {' '};' < ${SC_DFLT_FONT}-8x14 >> font.h && uudecode < /usr/share/syscons/fonts/${SC_DFLT_FONT}-8x8.fnt && file2c 'static u_char dflt_font_8[8*256] = {' '};' < ${SC_DFLT_FONT}-8x8 >> font.h" \ no-obj no-implicit-rule before-depend \ clean "font.h ${SC_DFLT_FONT}-8x14 ${SC_DFLT_FONT}-8x16 ${SC_DFLT_FONT}-8x8" # atkbdmap.h optional atkbd_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -L ${ATKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > atkbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "atkbdmap.h" # ukbdmap.h optional ukbd_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -L ${UKBD_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > ukbdmap.h" \ no-obj no-implicit-rule before-depend \ clean "ukbdmap.h" # hpt27xx_lib.o optional hpt27xx \ dependency "$S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \ compile-with "uudecode < $S/dev/hpt27xx/i386-elf.hpt27xx_lib.o.uu" \ no-implicit-rule # hptmvraid.o optional hptmv \ dependency "$S/dev/hptmv/i386-elf.raid.o.uu" \ compile-with "uudecode < $S/dev/hptmv/i386-elf.raid.o.uu" \ no-implicit-rule # hptnr_lib.o optional hptnr \ dependency "$S/dev/hptnr/i386-elf.hptnr_lib.o.uu" \ compile-with "uudecode < $S/dev/hptnr/i386-elf.hptnr_lib.o.uu" \ no-implicit-rule # hptrr_lib.o optional hptrr \ dependency "$S/dev/hptrr/i386-elf.hptrr_lib.o.uu" \ compile-with "uudecode < $S/dev/hptrr/i386-elf.hptrr_lib.o.uu" \ no-implicit-rule # cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S optional zfs | dtrace compile-with "${ZFS_S}" cddl/dev/dtrace/i386/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/i386/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}" cddl/dev/dtrace/i386/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}" compat/linprocfs/linprocfs.c optional linprocfs compat/linsysfs/linsysfs.c optional linsysfs compat/linux/linux_event.c optional compat_linux compat/linux/linux_emul.c optional compat_linux compat/linux/linux_file.c optional compat_linux compat/linux/linux_fork.c optional compat_linux compat/linux/linux_futex.c optional compat_linux compat/linux/linux_getcwd.c optional compat_linux compat/linux/linux_ioctl.c optional compat_linux compat/linux/linux_ipc.c optional compat_linux compat/linux/linux_mib.c optional compat_linux compat/linux/linux_misc.c optional compat_linux compat/linux/linux_mmap.c optional compat_linux compat/linux/linux_signal.c optional compat_linux compat/linux/linux_socket.c optional compat_linux compat/linux/linux_stats.c optional compat_linux compat/linux/linux_sysctl.c optional compat_linux compat/linux/linux_time.c optional compat_linux compat/linux/linux_timer.c optional compat_linux compat/linux/linux_uid16.c optional compat_linux compat/linux/linux_util.c optional compat_linux compat/linux/linux_vdso.c optional compat_linux compat/linux/linux.c optional compat_linux compat/ndis/kern_ndis.c optional ndisapi pci compat/ndis/kern_windrv.c optional ndisapi pci compat/ndis/subr_hal.c optional ndisapi pci compat/ndis/subr_ndis.c optional ndisapi pci compat/ndis/subr_ntoskrnl.c optional ndisapi pci compat/ndis/subr_pe.c optional ndisapi pci compat/ndis/subr_usbd.c optional ndisapi pci compat/ndis/winx32_wrap.S optional ndisapi pci compat/svr4/imgact_svr4.c optional compat_svr4 compat/svr4/svr4_fcntl.c optional compat_svr4 compat/svr4/svr4_filio.c optional compat_svr4 compat/svr4/svr4_ioctl.c optional compat_svr4 compat/svr4/svr4_ipc.c optional compat_svr4 compat/svr4/svr4_misc.c optional compat_svr4 compat/svr4/svr4_resource.c optional compat_svr4 compat/svr4/svr4_signal.c optional compat_svr4 compat/svr4/svr4_socket.c optional compat_svr4 compat/svr4/svr4_sockio.c optional compat_svr4 compat/svr4/svr4_stat.c optional compat_svr4 compat/svr4/svr4_stream.c optional compat_svr4 compat/svr4/svr4_syscallnames.c optional compat_svr4 compat/svr4/svr4_sysent.c optional compat_svr4 compat/svr4/svr4_sysvec.c optional compat_svr4 compat/svr4/svr4_termios.c optional compat_svr4 bf_enc.o optional crypto | ipsec | ipsec_support \ dependency "$S/crypto/blowfish/arch/i386/bf_enc.S $S/crypto/blowfish/arch/i386/bf_enc_586.S $S/crypto/blowfish/arch/i386/bf_enc_686.S" \ compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \ no-implicit-rule crypto/aesni/aeskeys_i386.S optional aesni crypto/aesni/aesni.c optional aesni aesni_ghash.o optional aesni \ dependency "$S/crypto/aesni/aesni_ghash.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes -mpclmul ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_ghash.o" aesni_wrap.o optional aesni \ dependency "$S/crypto/aesni/aesni_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc} ${WERROR} ${NO_WCAST_QUAL} ${PROF} -mmmx -msse -msse4 -maes ${.IMPSRC}" \ no-implicit-rule \ clean "aesni_wrap.o" crypto/des/arch/i386/des_enc.S optional crypto | ipsec | ipsec_support | netsmb crypto/via/padlock.c optional padlock crypto/via/padlock_cipher.c optional padlock crypto/via/padlock_hash.c optional padlock dev/advansys/adv_isa.c optional adv isa dev/agp/agp_ali.c optional agp dev/agp/agp_amd.c optional agp dev/agp/agp_amd64.c optional agp dev/agp/agp_ati.c optional agp dev/agp/agp_i810.c optional agp dev/agp/agp_intel.c optional agp dev/agp/agp_nvidia.c optional agp dev/agp/agp_sis.c optional agp dev/agp/agp_via.c optional agp dev/aic/aic_isa.c optional aic isa dev/amdsbwd/amdsbwd.c optional amdsbwd dev/amdtemp/amdtemp.c optional amdtemp dev/arcmsr/arcmsr.c optional arcmsr pci dev/asmc/asmc.c optional asmc isa dev/atkbdc/atkbd.c optional atkbd atkbdc dev/atkbdc/atkbd_atkbdc.c optional atkbd atkbdc dev/atkbdc/atkbdc.c optional atkbdc dev/atkbdc/atkbdc_isa.c optional atkbdc isa dev/atkbdc/atkbdc_subr.c optional atkbdc dev/atkbdc/psm.c optional psm atkbdc dev/bxe/bxe.c optional bxe pci dev/bxe/bxe_stats.c optional bxe pci dev/bxe/bxe_debug.c optional bxe pci dev/bxe/ecore_sp.c optional bxe pci dev/bxe/bxe_elink.c optional bxe pci dev/bxe/57710_init_values.c optional bxe pci dev/bxe/57711_init_values.c optional bxe pci dev/bxe/57712_init_values.c optional bxe pci dev/ce/ceddk.c optional ce dev/ce/if_ce.c optional ce dev/ce/tau32-ddk.c optional ce \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/cm/if_cm_isa.c optional cm isa dev/coretemp/coretemp.c optional coretemp dev/cp/cpddk.c optional cp dev/cp/if_cp.c optional cp dev/cpuctl/cpuctl.c optional cpuctl dev/ctau/ctau.c optional ctau dev/ctau/ctddk.c optional ctau dev/ctau/if_ct.c optional ctau dev/cx/csigma.c optional cx dev/cx/cxddk.c optional cx dev/cx/if_cx.c optional cx dev/dpms/dpms.c optional dpms dev/ed/if_ed_3c503.c optional ed isa ed_3c503 dev/ed/if_ed_isa.c optional ed isa dev/ed/if_ed_wd80x3.c optional ed isa dev/ed/if_ed_hpp.c optional ed isa ed_hpp dev/ed/if_ed_sic.c optional ed isa ed_sic dev/fb/fb.c optional fb | vga dev/fb/s3_pci.c optional s3pci dev/fb/vesa.c optional vga vesa dev/fb/vga.c optional vga dev/fdc/fdc.c optional fdc dev/fdc/fdc_acpi.c optional fdc dev/fdc/fdc_isa.c optional fdc isa dev/fdc/fdc_pccard.c optional fdc pccard dev/fe/if_fe_isa.c optional fe isa dev/glxiic/glxiic.c optional glxiic dev/glxsb/glxsb.c optional glxsb dev/glxsb/glxsb_hash.c optional glxsb dev/gpio/bytgpio.c optional bytgpio dev/hpt27xx/hpt27xx_os_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_osm_bsd.c optional hpt27xx dev/hpt27xx/hpt27xx_config.c optional hpt27xx dev/hptmv/entry.c optional hptmv dev/hptmv/mv.c optional hptmv dev/hptmv/gui_lib.c optional hptmv dev/hptmv/hptproc.c optional hptmv dev/hptmv/ioctl.c optional hptmv dev/hptnr/hptnr_os_bsd.c optional hptnr dev/hptnr/hptnr_osm_bsd.c optional hptnr dev/hptnr/hptnr_config.c optional hptnr dev/hptrr/hptrr_os_bsd.c optional hptrr dev/hptrr/hptrr_osm_bsd.c optional hptrr dev/hptrr/hptrr_config.c optional hptrr dev/hwpmc/hwpmc_amd.c optional hwpmc dev/hwpmc/hwpmc_intel.c optional hwpmc dev/hwpmc/hwpmc_core.c optional hwpmc dev/hwpmc/hwpmc_uncore.c optional hwpmc dev/hwpmc/hwpmc_pentium.c optional hwpmc dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_ppro.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/pcib/vmbus_pcib.c optional hyperv pci dev/hyperv/netvsc/hn_nvs.c optional hyperv dev/hyperv/netvsc/hn_rndis.c optional hyperv dev/hyperv/netvsc/if_hn.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv dev/hyperv/utilities/hv_snapshot.c optional hyperv dev/hyperv/utilities/vmbus_heartbeat.c optional hyperv dev/hyperv/utilities/vmbus_ic.c optional hyperv dev/hyperv/utilities/vmbus_shutdown.c optional hyperv dev/hyperv/utilities/vmbus_timesync.c optional hyperv dev/hyperv/vmbus/hyperv.c optional hyperv dev/hyperv/vmbus/hyperv_busdma.c optional hyperv dev/hyperv/vmbus/vmbus.c optional hyperv pci dev/hyperv/vmbus/vmbus_br.c optional hyperv dev/hyperv/vmbus/vmbus_chan.c optional hyperv dev/hyperv/vmbus/vmbus_et.c optional hyperv dev/hyperv/vmbus/vmbus_if.m optional hyperv dev/hyperv/vmbus/vmbus_res.c optional hyperv dev/hyperv/vmbus/vmbus_xact.c optional hyperv dev/hyperv/vmbus/i386/hyperv_machdep.c optional hyperv dev/hyperv/vmbus/i386/vmbus_vector.S optional hyperv dev/ichwd/ichwd.c optional ichwd dev/if_ndis/if_ndis.c optional ndis dev/if_ndis/if_ndis_pccard.c optional ndis pccard dev/if_ndis/if_ndis_pci.c optional ndis cardbus | ndis pci dev/if_ndis/if_ndis_usb.c optional ndis usb dev/intel/spi.c optional intelspi dev/io/iodev.c optional io dev/ipmi/ipmi.c optional ipmi dev/ipmi/ipmi_acpi.c optional ipmi acpi dev/ipmi/ipmi_isa.c optional ipmi isa dev/ipmi/ipmi_kcs.c optional ipmi dev/ipmi/ipmi_smic.c optional ipmi dev/ipmi/ipmi_smbus.c optional ipmi smbus dev/ipmi/ipmi_smbios.c optional ipmi dev/ipmi/ipmi_ssif.c optional ipmi smbus dev/ipmi/ipmi_pci.c optional ipmi pci dev/ipmi/ipmi_linux.c optional ipmi compat_linux dev/le/if_le_isa.c optional le isa dev/mse/mse.c optional mse dev/mse/mse_isa.c optional mse isa dev/nctgpio/nctgpio.c optional nctgpio dev/nfe/if_nfe.c optional nfe pci dev/ntb/if_ntb/if_ntb.c optional if_ntb -dev/ntb/ntb_transport.c optional if_ntb -dev/ntb/ntb.c optional if_ntb | ntb_hw -dev/ntb/ntb_if.m optional if_ntb | ntb_hw -dev/ntb/ntb_hw/ntb_hw.c optional ntb_hw +dev/ntb/ntb_transport.c optional ntb_transport | if_ntb +dev/ntb/ntb.c optional ntb | ntb_transport | if_ntb | ntb_hw_intel | ntb_hw_plx | ntb_hw +dev/ntb/ntb_if.m optional ntb | ntb_transport | if_ntb | ntb_hw_intel | ntb_hw_plx | ntb_hw +dev/ntb/ntb_hw/ntb_hw_intel.c optional ntb_hw_intel | ntb_hw +dev/ntb/ntb_hw/ntb_hw_plx.c optional ntb_hw_plx | ntb_hw dev/nvd/nvd.c optional nvd nvme dev/nvme/nvme.c optional nvme dev/nvme/nvme_ctrlr.c optional nvme dev/nvme/nvme_ctrlr_cmd.c optional nvme dev/nvme/nvme_ns.c optional nvme dev/nvme/nvme_ns_cmd.c optional nvme dev/nvme/nvme_qpair.c optional nvme dev/nvme/nvme_sysctl.c optional nvme dev/nvme/nvme_test.c optional nvme dev/nvme/nvme_util.c optional nvme dev/nvram/nvram.c optional nvram isa dev/ofw/ofwpci.c optional fdt pci dev/pcf/pcf_isa.c optional pcf dev/random/ivy.c optional rdrand_rng dev/random/nehemiah.c optional padlock_rng dev/sbni/if_sbni.c optional sbni dev/sbni/if_sbni_isa.c optional sbni isa dev/sbni/if_sbni_pci.c optional sbni pci dev/sio/sio.c optional sio dev/sio/sio_isa.c optional sio isa dev/sio/sio_pccard.c optional sio pccard dev/sio/sio_pci.c optional sio pci dev/sio/sio_puc.c optional sio puc dev/speaker/spkr.c optional speaker dev/syscons/apm/apm_saver.c optional apm_saver apm dev/syscons/scterm-teken.c optional sc dev/syscons/scvesactl.c optional sc vga vesa dev/syscons/scvgarndr.c optional sc vga dev/syscons/scvtb.c optional sc dev/tpm/tpm.c optional tpm dev/tpm/tpm_acpi.c optional tpm acpi dev/tpm/tpm_isa.c optional tpm isa dev/uart/uart_cpu_x86.c optional uart dev/viawd/viawd.c optional viawd dev/vmware/vmxnet3/if_vmx.c optional vmx dev/acpica/acpi_if.m standard dev/acpica/acpi_hpet.c optional acpi dev/acpi_support/acpi_wmi_if.m standard dev/wbwd/wbwd.c optional wbwd dev/wpi/if_wpi.c optional wpi dev/isci/isci.c optional isci dev/isci/isci_controller.c optional isci dev/isci/isci_domain.c optional isci dev/isci/isci_interrupt.c optional isci dev/isci/isci_io_request.c optional isci dev/isci/isci_logger.c optional isci dev/isci/isci_oem_parameters.c optional isci dev/isci/isci_remote_device.c optional isci dev/isci/isci_sysctl.c optional isci dev/isci/isci_task_request.c optional isci dev/isci/isci_timer.c optional isci dev/isci/scil/sati.c optional isci dev/isci/scil/sati_abort_task_set.c optional isci dev/isci/scil/sati_atapi.c optional isci dev/isci/scil/sati_device.c optional isci dev/isci/scil/sati_inquiry.c optional isci dev/isci/scil/sati_log_sense.c optional isci dev/isci/scil/sati_lun_reset.c optional isci dev/isci/scil/sati_mode_pages.c optional isci dev/isci/scil/sati_mode_select.c optional isci dev/isci/scil/sati_mode_sense.c optional isci dev/isci/scil/sati_mode_sense_10.c optional isci dev/isci/scil/sati_mode_sense_6.c optional isci dev/isci/scil/sati_move.c optional isci dev/isci/scil/sati_passthrough.c optional isci dev/isci/scil/sati_read.c optional isci dev/isci/scil/sati_read_buffer.c optional isci dev/isci/scil/sati_read_capacity.c optional isci dev/isci/scil/sati_reassign_blocks.c optional isci dev/isci/scil/sati_report_luns.c optional isci dev/isci/scil/sati_request_sense.c optional isci dev/isci/scil/sati_start_stop_unit.c optional isci dev/isci/scil/sati_synchronize_cache.c optional isci dev/isci/scil/sati_test_unit_ready.c optional isci dev/isci/scil/sati_unmap.c optional isci dev/isci/scil/sati_util.c optional isci dev/isci/scil/sati_verify.c optional isci dev/isci/scil/sati_write.c optional isci dev/isci/scil/sati_write_and_verify.c optional isci dev/isci/scil/sati_write_buffer.c optional isci dev/isci/scil/sati_write_long.c optional isci dev/isci/scil/sci_abstract_list.c optional isci dev/isci/scil/sci_base_controller.c optional isci dev/isci/scil/sci_base_domain.c optional isci dev/isci/scil/sci_base_iterator.c optional isci dev/isci/scil/sci_base_library.c optional isci dev/isci/scil/sci_base_logger.c optional isci dev/isci/scil/sci_base_memory_descriptor_list.c optional isci dev/isci/scil/sci_base_memory_descriptor_list_decorator.c optional isci dev/isci/scil/sci_base_object.c optional isci dev/isci/scil/sci_base_observer.c optional isci dev/isci/scil/sci_base_phy.c optional isci dev/isci/scil/sci_base_port.c optional isci dev/isci/scil/sci_base_remote_device.c optional isci dev/isci/scil/sci_base_request.c optional isci dev/isci/scil/sci_base_state_machine.c optional isci dev/isci/scil/sci_base_state_machine_logger.c optional isci dev/isci/scil/sci_base_state_machine_observer.c optional isci dev/isci/scil/sci_base_subject.c optional isci dev/isci/scil/sci_util.c optional isci dev/isci/scil/scic_sds_controller.c optional isci dev/isci/scil/scic_sds_library.c optional isci dev/isci/scil/scic_sds_pci.c optional isci dev/isci/scil/scic_sds_phy.c optional isci dev/isci/scil/scic_sds_port.c optional isci dev/isci/scil/scic_sds_port_configuration_agent.c optional isci dev/isci/scil/scic_sds_remote_device.c optional isci dev/isci/scil/scic_sds_remote_node_context.c optional isci dev/isci/scil/scic_sds_remote_node_table.c optional isci dev/isci/scil/scic_sds_request.c optional isci dev/isci/scil/scic_sds_sgpio.c optional isci dev/isci/scil/scic_sds_smp_remote_device.c optional isci dev/isci/scil/scic_sds_smp_request.c optional isci dev/isci/scil/scic_sds_ssp_request.c optional isci dev/isci/scil/scic_sds_stp_packet_request.c optional isci dev/isci/scil/scic_sds_stp_remote_device.c optional isci dev/isci/scil/scic_sds_stp_request.c optional isci dev/isci/scil/scic_sds_unsolicited_frame_control.c optional isci dev/isci/scil/scif_sas_controller.c optional isci dev/isci/scil/scif_sas_controller_state_handlers.c optional isci dev/isci/scil/scif_sas_controller_states.c optional isci dev/isci/scil/scif_sas_domain.c optional isci dev/isci/scil/scif_sas_domain_state_handlers.c optional isci dev/isci/scil/scif_sas_domain_states.c optional isci dev/isci/scil/scif_sas_high_priority_request_queue.c optional isci dev/isci/scil/scif_sas_internal_io_request.c optional isci dev/isci/scil/scif_sas_io_request.c optional isci dev/isci/scil/scif_sas_io_request_state_handlers.c optional isci dev/isci/scil/scif_sas_io_request_states.c optional isci dev/isci/scil/scif_sas_library.c optional isci dev/isci/scil/scif_sas_remote_device.c optional isci dev/isci/scil/scif_sas_remote_device_ready_substate_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_ready_substates.c optional isci dev/isci/scil/scif_sas_remote_device_starting_substate_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_starting_substates.c optional isci dev/isci/scil/scif_sas_remote_device_state_handlers.c optional isci dev/isci/scil/scif_sas_remote_device_states.c optional isci dev/isci/scil/scif_sas_request.c optional isci dev/isci/scil/scif_sas_smp_activity_clear_affiliation.c optional isci dev/isci/scil/scif_sas_smp_io_request.c optional isci dev/isci/scil/scif_sas_smp_phy.c optional isci dev/isci/scil/scif_sas_smp_remote_device.c optional isci dev/isci/scil/scif_sas_stp_io_request.c optional isci dev/isci/scil/scif_sas_stp_remote_device.c optional isci dev/isci/scil/scif_sas_stp_task_request.c optional isci dev/isci/scil/scif_sas_task_request.c optional isci dev/isci/scil/scif_sas_task_request_state_handlers.c optional isci dev/isci/scil/scif_sas_task_request_states.c optional isci dev/isci/scil/scif_sas_timer.c optional isci i386/acpica/acpi_machdep.c optional acpi acpi_wakecode.o optional acpi \ dependency "$S/i386/acpica/acpi_wakecode.S assym.s" \ compile-with "${NORMAL_S}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.o" acpi_wakecode.bin optional acpi \ dependency "acpi_wakecode.o" \ compile-with "${OBJCOPY} -S -O binary acpi_wakecode.o ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.bin" acpi_wakecode.h optional acpi \ dependency "acpi_wakecode.bin" \ compile-with "file2c -sx 'static char wakecode[] = {' '};' < acpi_wakecode.bin > ${.TARGET}" \ no-obj no-implicit-rule before-depend \ clean "acpi_wakecode.h" acpi_wakedata.h optional acpi \ dependency "acpi_wakecode.o" \ compile-with '${NM} -n --defined-only acpi_wakecode.o | while read offset dummy what; do echo "#define $${what} 0x$${offset}"; done > ${.TARGET}' \ no-obj no-implicit-rule before-depend \ clean "acpi_wakedata.h" # i386/bios/apm.c optional apm i386/bios/mca_machdep.c optional mca i386/bios/smapi.c optional smapi i386/bios/smapi_bios.S optional smapi i386/cloudabi32/cloudabi32_sysvec.c optional compat_cloudabi32 #i386/i386/apic_vector.s optional apic i386/i386/atomic.c standard \ compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}" i386/i386/bios.c standard i386/i386/bioscall.s standard i386/i386/bpf_jit_machdep.c optional bpf_jitter i386/i386/db_disasm.c optional ddb i386/i386/db_interface.c optional ddb i386/i386/db_trace.c optional ddb i386/i386/elan-mmcr.c optional cpu_elan | cpu_soekris i386/i386/elf_machdep.c standard i386/i386/exception.s standard i386/i386/gdb_machdep.c optional gdb i386/i386/geode.c optional cpu_geode i386/i386/in_cksum.c optional inet | inet6 i386/i386/initcpu.c standard i386/i386/io.c optional io i386/i386/k6_mem.c optional mem i386/i386/locore.s standard no-obj i386/i386/longrun.c optional cpu_enable_longrun i386/i386/machdep.c standard i386/i386/mem.c optional mem i386/i386/minidump_machdep.c standard i386/i386/mp_clock.c optional smp i386/i386/mp_machdep.c optional smp i386/i386/mpboot.s optional smp i386/i386/perfmon.c optional perfmon i386/i386/pmap.c standard i386/i386/ptrace_machdep.c standard i386/i386/support.s standard i386/i386/swtch.s standard i386/i386/sys_machdep.c standard i386/i386/trap.c standard i386/i386/uio_machdep.c standard i386/i386/vm86.c standard i386/i386/vm_machdep.c standard i386/ibcs2/ibcs2_errno.c optional ibcs2 i386/ibcs2/ibcs2_fcntl.c optional ibcs2 i386/ibcs2/ibcs2_ioctl.c optional ibcs2 i386/ibcs2/ibcs2_ipc.c optional ibcs2 i386/ibcs2/ibcs2_isc.c optional ibcs2 i386/ibcs2/ibcs2_isc_sysent.c optional ibcs2 i386/ibcs2/ibcs2_misc.c optional ibcs2 i386/ibcs2/ibcs2_msg.c optional ibcs2 i386/ibcs2/ibcs2_other.c optional ibcs2 i386/ibcs2/ibcs2_signal.c optional ibcs2 i386/ibcs2/ibcs2_socksys.c optional ibcs2 i386/ibcs2/ibcs2_stat.c optional ibcs2 i386/ibcs2/ibcs2_sysent.c optional ibcs2 i386/ibcs2/ibcs2_sysi86.c optional ibcs2 i386/ibcs2/ibcs2_sysvec.c optional ibcs2 i386/ibcs2/ibcs2_util.c optional ibcs2 i386/ibcs2/ibcs2_xenix.c optional ibcs2 i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2 i386/ibcs2/imgact_coff.c optional ibcs2 i386/isa/elink.c optional ep | ie i386/isa/npx.c standard i386/isa/pmtimer.c optional pmtimer i386/isa/prof_machdep.c optional profiling-routine i386/isa/spic.c optional spic i386/linux/imgact_linux.c optional compat_linux i386/linux/linux_dummy.c optional compat_linux i386/linux/linux_machdep.c optional compat_linux i386/linux/linux_ptrace.c optional compat_linux i386/linux/linux_support.s optional compat_linux \ dependency "linux_assym.h" i386/linux/linux_sysent.c optional compat_linux i386/linux/linux_sysvec.c optional compat_linux i386/pci/pci_cfgreg.c optional pci i386/pci/pci_pir.c optional pci i386/svr4/svr4_locore.s optional compat_svr4 \ dependency "svr4_assym.h" \ warning "COMPAT_SVR4 is broken and should be avoided" i386/svr4/svr4_machdep.c optional compat_svr4 # isa/syscons_isa.c optional sc isa/vga_isa.c optional vga kern/kern_clocksource.c standard kern/imgact_aout.c optional compat_aout kern/imgact_gzip.c optional gzip kern/subr_sfbuf.c standard libkern/divdi3.c standard libkern/ffsll.c standard libkern/flsll.c standard libkern/memmove.c standard libkern/memset.c standard libkern/moddi3.c standard libkern/qdivrem.c standard libkern/ucmpdi2.c standard libkern/udivdi3.c standard libkern/umoddi3.c standard libkern/x86/crc32_sse42.c standard i386/xbox/xbox.c optional xbox i386/xbox/xboxfb.c optional xboxfb dev/fb/boot_font.c optional xboxfb i386/xbox/pic16l.s optional xbox # # x86 real mode BIOS support, required by dpms/pci/vesa # compat/x86bios/x86bios.c optional x86bios | dpms | pci | vesa # # bvm console # dev/bvm/bvm_console.c optional bvmconsole dev/bvm/bvm_dbg.c optional bvmdebug # # x86 shared code between IA32, AMD64 and PC98 architectures # x86/acpica/OsdEnvironment.c optional acpi x86/acpica/acpi_apm.c optional acpi x86/acpica/acpi_wakeup.c optional acpi x86/acpica/madt.c optional acpi apic x86/acpica/srat.c optional acpi x86/bios/smbios.c optional smbios x86/bios/vpd.c optional vpd x86/cpufreq/est.c optional cpufreq x86/cpufreq/hwpstate.c optional cpufreq x86/cpufreq/p4tcc.c optional cpufreq x86/cpufreq/powernow.c optional cpufreq x86/cpufreq/smist.c optional cpufreq x86/iommu/busdma_dmar.c optional acpi acpi_dmar pci x86/iommu/intel_ctx.c optional acpi acpi_dmar pci x86/iommu/intel_drv.c optional acpi acpi_dmar pci x86/iommu/intel_fault.c optional acpi acpi_dmar pci x86/iommu/intel_gas.c optional acpi acpi_dmar pci x86/iommu/intel_idpgtbl.c optional acpi acpi_dmar pci x86/iommu/intel_intrmap.c optional acpi acpi_dmar pci x86/iommu/intel_qi.c optional acpi acpi_dmar pci x86/iommu/intel_quirks.c optional acpi acpi_dmar pci x86/iommu/intel_utils.c optional acpi acpi_dmar pci x86/isa/atpic.c optional atpic x86/isa/atrtc.c standard x86/isa/clock.c standard x86/isa/elcr.c optional atpic | apic x86/isa/isa.c optional isa x86/isa/isa_dma.c optional isa x86/isa/nmi.c standard x86/isa/orm.c optional isa x86/pci/pci_bus.c optional pci x86/pci/qpi.c optional pci x86/x86/autoconf.c standard x86/x86/bus_machdep.c standard x86/x86/busdma_bounce.c standard x86/x86/busdma_machdep.c standard x86/x86/cpu_machdep.c standard x86/x86/dump_machdep.c standard x86/x86/fdt_machdep.c optional fdt x86/x86/identcpu.c standard x86/x86/intr_machdep.c standard x86/x86/io_apic.c optional apic x86/x86/legacy.c standard x86/x86/local_apic.c optional apic x86/x86/mca.c standard x86/x86/x86_mem.c optional mem x86/x86/mptable.c optional apic x86/x86/mptable_pci.c optional apic pci x86/x86/mp_x86.c optional smp x86/x86/mp_watchdog.c optional mp_watchdog smp x86/x86/msi.c optional apic pci x86/x86/nexus.c standard x86/x86/stack_machdep.c optional ddb | stack x86/x86/tsc.c standard x86/x86/pvclock.c standard x86/x86/delay.c standard x86/xen/hvm.c optional xenhvm x86/xen/xen_intr.c optional xenhvm x86/xen/xen_apic.c optional xenhvm x86/xen/xenpv.c optional xenhvm x86/xen/xen_nexus.c optional xenhvm x86/xen/xen_msi.c optional xenhvm Index: stable/11/sys/dev/ntb/ntb_hw/ntb_regs.h =================================================================== --- stable/11/sys/dev/ntb/ntb_hw/ntb_regs.h (revision 323452) +++ stable/11/sys/dev/ntb/ntb_hw/ntb_regs.h (nonexistent) @@ -1,168 +0,0 @@ -/*- - * Copyright (c) 2016 Alexander Motin - * Copyright (C) 2013 Intel Corporation - * Copyright (C) 2015 EMC Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _NTB_REGS_H_ -#define _NTB_REGS_H_ - -#define NTB_LINK_STATUS_ACTIVE 0x2000 -#define NTB_LINK_SPEED_MASK 0x000f -#define NTB_LINK_WIDTH_MASK 0x03f0 -#define NTB_LNK_STA_WIDTH(sta) (((sta) & NTB_LINK_WIDTH_MASK) >> 4) - -#define XEON_SNB_MW_COUNT 2 -#define XEON_HSX_SPLIT_MW_COUNT 3 -/* Reserve the uppermost bit for link interrupt */ -#define XEON_DB_COUNT 15 -#define XEON_DB_TOTAL_SHIFT 16 -#define XEON_DB_LINK 15 -#define XEON_DB_MSIX_VECTOR_COUNT 4 -#define XEON_DB_MSIX_VECTOR_SHIFT 5 -#define XEON_DB_LINK_BIT (1 << XEON_DB_LINK) -#define XEON_NONLINK_DB_MSIX_BITS 3 - -#define XEON_SPCICMD_OFFSET 0x0504 -#define XEON_DEVCTRL_OFFSET 0x0598 -#define XEON_DEVSTS_OFFSET 0x059a -#define XEON_LINK_STATUS_OFFSET 0x01a2 -#define XEON_SLINK_STATUS_OFFSET 0x05a2 - -#define XEON_PBAR2LMT_OFFSET 0x0000 -#define XEON_PBAR4LMT_OFFSET 0x0008 -#define XEON_PBAR5LMT_OFFSET 0x000c -#define XEON_PBAR2XLAT_OFFSET 0x0010 -#define XEON_PBAR4XLAT_OFFSET 0x0018 -#define XEON_PBAR5XLAT_OFFSET 0x001c -#define XEON_SBAR2LMT_OFFSET 0x0020 -#define XEON_SBAR4LMT_OFFSET 0x0028 -#define XEON_SBAR5LMT_OFFSET 0x002c -#define XEON_SBAR2XLAT_OFFSET 0x0030 -#define XEON_SBAR4XLAT_OFFSET 0x0038 -#define XEON_SBAR5XLAT_OFFSET 0x003c -#define XEON_SBAR0BASE_OFFSET 0x0040 -#define XEON_SBAR2BASE_OFFSET 0x0048 -#define XEON_SBAR4BASE_OFFSET 0x0050 -#define XEON_SBAR5BASE_OFFSET 0x0054 -#define XEON_NTBCNTL_OFFSET 0x0058 -#define XEON_SBDF_OFFSET 0x005c -#define XEON_PDOORBELL_OFFSET 0x0060 -#define XEON_PDBMSK_OFFSET 0x0062 -#define XEON_SDOORBELL_OFFSET 0x0064 -#define XEON_SDBMSK_OFFSET 0x0066 -#define XEON_USMEMMISS_OFFSET 0x0070 -#define XEON_SPAD_OFFSET 0x0080 -#define XEON_SPAD_COUNT 16 -#define XEON_SPADSEMA4_OFFSET 0x00c0 -#define XEON_WCCNTRL_OFFSET 0x00e0 -#define XEON_UNCERRSTS_OFFSET 0x014c -#define XEON_CORERRSTS_OFFSET 0x0158 -#define XEON_B2B_SPAD_OFFSET 0x0100 -#define XEON_B2B_DOORBELL_OFFSET 0x0140 -#define XEON_B2B_XLAT_OFFSETL 0x0144 -#define XEON_B2B_XLAT_OFFSETU 0x0148 - -#define ATOM_MW_COUNT 2 -#define ATOM_DB_COUNT 34 -#define ATOM_DB_MSIX_VECTOR_COUNT 34 -#define ATOM_DB_MSIX_VECTOR_SHIFT 1 - -#define ATOM_SPCICMD_OFFSET 0xb004 -#define ATOM_MBAR23_OFFSET 0xb018 -#define ATOM_MBAR45_OFFSET 0xb020 -#define ATOM_DEVCTRL_OFFSET 0xb048 -#define ATOM_LINK_STATUS_OFFSET 0xb052 -#define ATOM_ERRCORSTS_OFFSET 0xb110 - -#define ATOM_SBAR2XLAT_OFFSET 0x0008 -#define ATOM_SBAR4XLAT_OFFSET 0x0010 -#define ATOM_PDOORBELL_OFFSET 0x0020 -#define ATOM_PDBMSK_OFFSET 0x0028 -#define ATOM_NTBCNTL_OFFSET 0x0060 -#define ATOM_EBDF_OFFSET 0x0064 -#define ATOM_SPAD_OFFSET 0x0080 -#define ATOM_SPAD_COUNT 16 -#define ATOM_SPADSEMA_OFFSET 0x00c0 -#define ATOM_STKYSPAD_OFFSET 0x00c4 -#define ATOM_PBAR2XLAT_OFFSET 0x8008 -#define ATOM_PBAR4XLAT_OFFSET 0x8010 -#define ATOM_B2B_DOORBELL_OFFSET 0x8020 -#define ATOM_B2B_SPAD_OFFSET 0x8080 -#define ATOM_B2B_SPADSEMA_OFFSET 0x80c0 -#define ATOM_B2B_STKYSPAD_OFFSET 0x80c4 - -#define ATOM_MODPHY_PCSREG4 0x1c004 -#define ATOM_MODPHY_PCSREG6 0x1c006 - -#define ATOM_IP_BASE 0xc000 -#define ATOM_DESKEWSTS_OFFSET (ATOM_IP_BASE + 0x3024) -#define ATOM_LTSSMERRSTS0_OFFSET (ATOM_IP_BASE + 0x3180) -#define ATOM_LTSSMSTATEJMP_OFFSET (ATOM_IP_BASE + 0x3040) -#define ATOM_IBSTERRRCRVSTS0_OFFSET (ATOM_IP_BASE + 0x3324) - -#define ATOM_DESKEWSTS_DBERR (1 << 15) -#define ATOM_LTSSMERRSTS0_UNEXPECTEDEI (1 << 20) -#define ATOM_LTSSMSTATEJMP_FORCEDETECT (1 << 2) -#define ATOM_IBIST_ERR_OFLOW 0x7fff7fff - -#define NTB_CNTL_CFG_LOCK (1 << 0) -#define NTB_CNTL_LINK_DISABLE (1 << 1) -#define NTB_CNTL_S2P_BAR23_SNOOP (1 << 2) -#define NTB_CNTL_P2S_BAR23_SNOOP (1 << 4) -#define NTB_CNTL_S2P_BAR4_SNOOP (1 << 6) -#define NTB_CNTL_P2S_BAR4_SNOOP (1 << 8) -#define NTB_CNTL_S2P_BAR5_SNOOP (1 << 12) -#define NTB_CNTL_P2S_BAR5_SNOOP (1 << 14) -#define ATOM_CNTL_LINK_DOWN (1 << 16) - -#define XEON_PBAR23SZ_OFFSET 0x00d0 -#define XEON_PBAR45SZ_OFFSET 0x00d1 -#define XEON_PBAR4SZ_OFFSET 0x00d1 -#define XEON_PBAR5SZ_OFFSET 0x00d5 -#define XEON_SBAR23SZ_OFFSET 0x00d2 -#define XEON_SBAR4SZ_OFFSET 0x00d3 -#define XEON_SBAR5SZ_OFFSET 0x00d6 -#define NTB_PPD_OFFSET 0x00d4 -#define XEON_PPD_CONN_TYPE 0x0003 -#define XEON_PPD_DEV_TYPE 0x0010 -#define XEON_PPD_SPLIT_BAR 0x0040 -#define ATOM_PPD_INIT_LINK 0x0008 -#define ATOM_PPD_CONN_TYPE 0x0300 -#define ATOM_PPD_DEV_TYPE 0x1000 - -/* All addresses are in low 32-bit space so 32-bit BARs can function */ -#define XEON_B2B_BAR0_ADDR 0x1000000000000000ull -#define XEON_B2B_BAR2_ADDR64 0x2000000000000000ull -#define XEON_B2B_BAR4_ADDR64 0x4000000000000000ull -#define XEON_B2B_BAR4_ADDR32 0x20000000ull -#define XEON_B2B_BAR5_ADDR32 0x40000000ull - -/* The peer ntb secondary config space is 32KB fixed size */ -#define XEON_B2B_MIN_SIZE 0x8000 - -#endif /* _NTB_REGS_H_ */ Property changes on: stable/11/sys/dev/ntb/ntb_hw/ntb_regs.h ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: stable/11/sys/dev/ntb/ntb_hw/ntb_hw.c =================================================================== --- stable/11/sys/dev/ntb/ntb_hw/ntb_hw.c (revision 323452) +++ stable/11/sys/dev/ntb/ntb_hw/ntb_hw.c (nonexistent) @@ -1,3121 +0,0 @@ -/*- - * Copyright (c) 2016 Alexander Motin - * Copyright (C) 2013 Intel Corporation - * Copyright (C) 2015 EMC Corporation - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * The Non-Transparent Bridge (NTB) is a device that allows you to connect - * two or more systems using a PCI-e links, providing remote memory access. - * - * This module contains a driver for NTB hardware in Intel Xeon/Atom CPUs. - * - * NOTE: Much of the code in this module is shared with Linux. Any patches may - * be picked up and redistributed in Linux with a dual GPL/BSD license. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ntb_regs.h" -#include "../ntb.h" - -#define MAX_MSIX_INTERRUPTS MAX(XEON_DB_COUNT, ATOM_DB_COUNT) - -#define NTB_HB_TIMEOUT 1 /* second */ -#define ATOM_LINK_RECOVERY_TIME 500 /* ms */ -#define BAR_HIGH_MASK (~((1ull << 12) - 1)) - -#define NTB_MSIX_VER_GUARD 0xaabbccdd -#define NTB_MSIX_RECEIVED 0xe0f0e0f0 - -/* - * PCI constants could be somewhere more generic, but aren't defined/used in - * pci.c. - */ -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 - -enum ntb_device_type { - NTB_XEON, - NTB_ATOM -}; - -/* ntb_conn_type are hardware numbers, cannot change. */ -enum ntb_conn_type { - NTB_CONN_TRANSPARENT = 0, - NTB_CONN_B2B = 1, - NTB_CONN_RP = 2, -}; - -enum ntb_b2b_direction { - NTB_DEV_USD = 0, - NTB_DEV_DSD = 1, -}; - -enum ntb_bar { - NTB_CONFIG_BAR = 0, - NTB_B2B_BAR_1, - NTB_B2B_BAR_2, - NTB_B2B_BAR_3, - NTB_MAX_BARS -}; - -enum { - NTB_MSIX_GUARD = 0, - NTB_MSIX_DATA0, - NTB_MSIX_DATA1, - NTB_MSIX_DATA2, - NTB_MSIX_OFS0, - NTB_MSIX_OFS1, - NTB_MSIX_OFS2, - NTB_MSIX_DONE, - NTB_MAX_MSIX_SPAD -}; - -/* Device features and workarounds */ -#define HAS_FEATURE(ntb, feature) \ - (((ntb)->features & (feature)) != 0) - -struct ntb_hw_info { - uint32_t device_id; - const char *desc; - enum ntb_device_type type; - uint32_t features; -}; - -struct ntb_pci_bar_info { - bus_space_tag_t pci_bus_tag; - bus_space_handle_t pci_bus_handle; - int pci_resource_id; - struct resource *pci_resource; - vm_paddr_t pbase; - caddr_t vbase; - vm_size_t size; - vm_memattr_t map_mode; - - /* Configuration register offsets */ - uint32_t psz_off; - uint32_t ssz_off; - uint32_t pbarxlat_off; -}; - -struct ntb_int_info { - struct resource *res; - int rid; - void *tag; -}; - -struct ntb_vec { - struct ntb_softc *ntb; - uint32_t num; - unsigned masked; -}; - -struct ntb_reg { - uint32_t ntb_ctl; - uint32_t lnk_sta; - uint8_t db_size; - unsigned mw_bar[NTB_MAX_BARS]; -}; - -struct ntb_alt_reg { - uint32_t db_bell; - uint32_t db_mask; - uint32_t spad; -}; - -struct ntb_xlat_reg { - uint32_t bar0_base; - uint32_t bar2_base; - uint32_t bar4_base; - uint32_t bar5_base; - - uint32_t bar2_xlat; - uint32_t bar4_xlat; - uint32_t bar5_xlat; - - uint32_t bar2_limit; - uint32_t bar4_limit; - uint32_t bar5_limit; -}; - -struct ntb_b2b_addr { - uint64_t bar0_addr; - uint64_t bar2_addr64; - uint64_t bar4_addr64; - uint64_t bar4_addr32; - uint64_t bar5_addr32; -}; - -struct ntb_msix_data { - uint32_t nmd_ofs; - uint32_t nmd_data; -}; - -struct ntb_softc { - /* ntb.c context. Do not move! Must go first! */ - void *ntb_store; - - device_t device; - enum ntb_device_type type; - uint32_t features; - - struct ntb_pci_bar_info bar_info[NTB_MAX_BARS]; - struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS]; - uint32_t allocated_interrupts; - - struct ntb_msix_data peer_msix_data[XEON_NONLINK_DB_MSIX_BITS]; - struct ntb_msix_data msix_data[XEON_NONLINK_DB_MSIX_BITS]; - bool peer_msix_good; - bool peer_msix_done; - struct ntb_pci_bar_info *peer_lapic_bar; - struct callout peer_msix_work; - - struct callout heartbeat_timer; - struct callout lr_timer; - - struct ntb_vec *msix_vec; - - uint32_t ppd; - enum ntb_conn_type conn_type; - enum ntb_b2b_direction dev_type; - - /* Offset of peer bar0 in B2B BAR */ - uint64_t b2b_off; - /* Memory window used to access peer bar0 */ -#define B2B_MW_DISABLED UINT8_MAX - uint8_t b2b_mw_idx; - uint32_t msix_xlat; - uint8_t msix_mw_idx; - - uint8_t mw_count; - uint8_t spad_count; - uint8_t db_count; - uint8_t db_vec_count; - uint8_t db_vec_shift; - - /* Protects local db_mask. */ -#define DB_MASK_LOCK(sc) mtx_lock_spin(&(sc)->db_mask_lock) -#define DB_MASK_UNLOCK(sc) mtx_unlock_spin(&(sc)->db_mask_lock) -#define DB_MASK_ASSERT(sc,f) mtx_assert(&(sc)->db_mask_lock, (f)) - struct mtx db_mask_lock; - - volatile uint32_t ntb_ctl; - volatile uint32_t lnk_sta; - - uint64_t db_valid_mask; - uint64_t db_link_mask; - uint64_t db_mask; - uint64_t fake_db; /* NTB_SB01BASE_LOCKUP*/ - uint64_t force_db; /* NTB_SB01BASE_LOCKUP*/ - - int last_ts; /* ticks @ last irq */ - - const struct ntb_reg *reg; - const struct ntb_alt_reg *self_reg; - const struct ntb_alt_reg *peer_reg; - const struct ntb_xlat_reg *xlat_reg; -}; - -#ifdef __i386__ -static __inline uint64_t -bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset) -{ - - return (bus_space_read_4(tag, handle, offset) | - ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32); -} - -static __inline void -bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t handle, - bus_size_t offset, uint64_t val) -{ - - bus_space_write_4(tag, handle, offset, val); - bus_space_write_4(tag, handle, offset + 4, val >> 32); -} -#endif - -#define intel_ntb_bar_read(SIZE, bar, offset) \ - bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ - ntb->bar_info[(bar)].pci_bus_handle, (offset)) -#define intel_ntb_bar_write(SIZE, bar, offset, val) \ - bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ - ntb->bar_info[(bar)].pci_bus_handle, (offset), (val)) -#define intel_ntb_reg_read(SIZE, offset) \ - intel_ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset) -#define intel_ntb_reg_write(SIZE, offset, val) \ - intel_ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val) -#define intel_ntb_mw_read(SIZE, offset) \ - intel_ntb_bar_read(SIZE, intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx), \ - offset) -#define intel_ntb_mw_write(SIZE, offset, val) \ - intel_ntb_bar_write(SIZE, intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx), \ - offset, val) - -static int intel_ntb_probe(device_t device); -static int intel_ntb_attach(device_t device); -static int intel_ntb_detach(device_t device); -static uint64_t intel_ntb_db_valid_mask(device_t dev); -static void intel_ntb_spad_clear(device_t dev); -static uint64_t intel_ntb_db_vector_mask(device_t dev, uint32_t vector); -static bool intel_ntb_link_is_up(device_t dev, enum ntb_speed *speed, - enum ntb_width *width); -static int intel_ntb_link_enable(device_t dev, enum ntb_speed speed, - enum ntb_width width); -static int intel_ntb_link_disable(device_t dev); -static int intel_ntb_spad_read(device_t dev, unsigned int idx, uint32_t *val); -static int intel_ntb_peer_spad_write(device_t dev, unsigned int idx, uint32_t val); - -static unsigned intel_ntb_user_mw_to_idx(struct ntb_softc *, unsigned uidx); -static inline enum ntb_bar intel_ntb_mw_to_bar(struct ntb_softc *, unsigned mw); -static inline bool bar_is_64bit(struct ntb_softc *, enum ntb_bar); -static inline void bar_get_xlat_params(struct ntb_softc *, enum ntb_bar, - uint32_t *base, uint32_t *xlat, uint32_t *lmt); -static int intel_ntb_map_pci_bars(struct ntb_softc *ntb); -static int intel_ntb_mw_set_wc_internal(struct ntb_softc *, unsigned idx, - vm_memattr_t); -static void print_map_success(struct ntb_softc *, struct ntb_pci_bar_info *, - const char *); -static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); -static int map_memory_window_bar(struct ntb_softc *ntb, - struct ntb_pci_bar_info *bar); -static void intel_ntb_unmap_pci_bar(struct ntb_softc *ntb); -static int intel_ntb_remap_msix(device_t, uint32_t desired, uint32_t avail); -static int intel_ntb_init_isr(struct ntb_softc *ntb); -static int intel_ntb_setup_legacy_interrupt(struct ntb_softc *ntb); -static int intel_ntb_setup_msix(struct ntb_softc *ntb, uint32_t num_vectors); -static void intel_ntb_teardown_interrupts(struct ntb_softc *ntb); -static inline uint64_t intel_ntb_vec_mask(struct ntb_softc *, uint64_t db_vector); -static void intel_ntb_interrupt(struct ntb_softc *, uint32_t vec); -static void ndev_vec_isr(void *arg); -static void ndev_irq_isr(void *arg); -static inline uint64_t db_ioread(struct ntb_softc *, uint64_t regoff); -static inline void db_iowrite(struct ntb_softc *, uint64_t regoff, uint64_t); -static inline void db_iowrite_raw(struct ntb_softc *, uint64_t regoff, uint64_t); -static int intel_ntb_create_msix_vec(struct ntb_softc *ntb, uint32_t num_vectors); -static void intel_ntb_free_msix_vec(struct ntb_softc *ntb); -static void intel_ntb_get_msix_info(struct ntb_softc *ntb); -static void intel_ntb_exchange_msix(void *); -static struct ntb_hw_info *intel_ntb_get_device_info(uint32_t device_id); -static void intel_ntb_detect_max_mw(struct ntb_softc *ntb); -static int intel_ntb_detect_xeon(struct ntb_softc *ntb); -static int intel_ntb_detect_atom(struct ntb_softc *ntb); -static int intel_ntb_xeon_init_dev(struct ntb_softc *ntb); -static int intel_ntb_atom_init_dev(struct ntb_softc *ntb); -static void intel_ntb_teardown_xeon(struct ntb_softc *ntb); -static void configure_atom_secondary_side_bars(struct ntb_softc *ntb); -static void xeon_reset_sbar_size(struct ntb_softc *, enum ntb_bar idx, - enum ntb_bar regbar); -static void xeon_set_sbar_base_and_limit(struct ntb_softc *, - uint64_t base_addr, enum ntb_bar idx, enum ntb_bar regbar); -static void xeon_set_pbar_xlat(struct ntb_softc *, uint64_t base_addr, - enum ntb_bar idx); -static int xeon_setup_b2b_mw(struct ntb_softc *, - const struct ntb_b2b_addr *addr, const struct ntb_b2b_addr *peer_addr); -static inline bool link_is_up(struct ntb_softc *ntb); -static inline bool _xeon_link_is_up(struct ntb_softc *ntb); -static inline bool atom_link_is_err(struct ntb_softc *ntb); -static inline enum ntb_speed intel_ntb_link_sta_speed(struct ntb_softc *); -static inline enum ntb_width intel_ntb_link_sta_width(struct ntb_softc *); -static void atom_link_hb(void *arg); -static void recover_atom_link(void *arg); -static bool intel_ntb_poll_link(struct ntb_softc *ntb); -static void save_bar_parameters(struct ntb_pci_bar_info *bar); -static void intel_ntb_sysctl_init(struct ntb_softc *); -static int sysctl_handle_features(SYSCTL_HANDLER_ARGS); -static int sysctl_handle_link_admin(SYSCTL_HANDLER_ARGS); -static int sysctl_handle_link_status_human(SYSCTL_HANDLER_ARGS); -static int sysctl_handle_link_status(SYSCTL_HANDLER_ARGS); -static int sysctl_handle_register(SYSCTL_HANDLER_ARGS); - -static unsigned g_ntb_hw_debug_level; -SYSCTL_UINT(_hw_ntb, OID_AUTO, debug_level, CTLFLAG_RWTUN, - &g_ntb_hw_debug_level, 0, "ntb_hw log level -- higher is more verbose"); -#define intel_ntb_printf(lvl, ...) do { \ - if ((lvl) <= g_ntb_hw_debug_level) { \ - device_printf(ntb->device, __VA_ARGS__); \ - } \ -} while (0) - -#define _NTB_PAT_UC 0 -#define _NTB_PAT_WC 1 -#define _NTB_PAT_WT 4 -#define _NTB_PAT_WP 5 -#define _NTB_PAT_WB 6 -#define _NTB_PAT_UCM 7 -static unsigned g_ntb_mw_pat = _NTB_PAT_UC; -SYSCTL_UINT(_hw_ntb, OID_AUTO, default_mw_pat, CTLFLAG_RDTUN, - &g_ntb_mw_pat, 0, "Configure the default memory window cache flags (PAT): " - "UC: " __XSTRING(_NTB_PAT_UC) ", " - "WC: " __XSTRING(_NTB_PAT_WC) ", " - "WT: " __XSTRING(_NTB_PAT_WT) ", " - "WP: " __XSTRING(_NTB_PAT_WP) ", " - "WB: " __XSTRING(_NTB_PAT_WB) ", " - "UC-: " __XSTRING(_NTB_PAT_UCM)); - -static inline vm_memattr_t -intel_ntb_pat_flags(void) -{ - - switch (g_ntb_mw_pat) { - case _NTB_PAT_WC: - return (VM_MEMATTR_WRITE_COMBINING); - case _NTB_PAT_WT: - return (VM_MEMATTR_WRITE_THROUGH); - case _NTB_PAT_WP: - return (VM_MEMATTR_WRITE_PROTECTED); - case _NTB_PAT_WB: - return (VM_MEMATTR_WRITE_BACK); - case _NTB_PAT_UCM: - return (VM_MEMATTR_WEAK_UNCACHEABLE); - case _NTB_PAT_UC: - /* FALLTHROUGH */ - default: - return (VM_MEMATTR_UNCACHEABLE); - } -} - -/* - * Well, this obviously doesn't belong here, but it doesn't seem to exist - * anywhere better yet. - */ -static inline const char * -intel_ntb_vm_memattr_to_str(vm_memattr_t pat) -{ - - switch (pat) { - case VM_MEMATTR_WRITE_COMBINING: - return ("WRITE_COMBINING"); - case VM_MEMATTR_WRITE_THROUGH: - return ("WRITE_THROUGH"); - case VM_MEMATTR_WRITE_PROTECTED: - return ("WRITE_PROTECTED"); - case VM_MEMATTR_WRITE_BACK: - return ("WRITE_BACK"); - case VM_MEMATTR_WEAK_UNCACHEABLE: - return ("UNCACHED"); - case VM_MEMATTR_UNCACHEABLE: - return ("UNCACHEABLE"); - default: - return ("UNKNOWN"); - } -} - -static int g_ntb_msix_idx = 1; -SYSCTL_INT(_hw_ntb, OID_AUTO, msix_mw_idx, CTLFLAG_RDTUN, &g_ntb_msix_idx, - 0, "Use this memory window to access the peer MSIX message complex on " - "certain Xeon-based NTB systems, as a workaround for a hardware errata. " - "Like b2b_mw_idx, negative values index from the last available memory " - "window. (Applies on Xeon platforms with SB01BASE_LOCKUP errata.)"); - -static int g_ntb_mw_idx = -1; -SYSCTL_INT(_hw_ntb, OID_AUTO, b2b_mw_idx, CTLFLAG_RDTUN, &g_ntb_mw_idx, - 0, "Use this memory window to access the peer NTB registers. A " - "non-negative value starts from the first MW index; a negative value " - "starts from the last MW index. The default is -1, i.e., the last " - "available memory window. Both sides of the NTB MUST set the same " - "value here! (Applies on Xeon platforms with SDOORBELL_LOCKUP errata.)"); - -/* Hardware owns the low 16 bits of features. */ -#define NTB_BAR_SIZE_4K (1 << 0) -#define NTB_SDOORBELL_LOCKUP (1 << 1) -#define NTB_SB01BASE_LOCKUP (1 << 2) -#define NTB_B2BDOORBELL_BIT14 (1 << 3) -/* Software/configuration owns the top 16 bits. */ -#define NTB_SPLIT_BAR (1ull << 16) - -#define NTB_FEATURES_STR \ - "\20\21SPLIT_BAR4\04B2B_DOORBELL_BIT14\03SB01BASE_LOCKUP" \ - "\02SDOORBELL_LOCKUP\01BAR_SIZE_4K" - -static struct ntb_hw_info pci_ids[] = { - /* XXX: PS/SS IDs left out until they are supported. */ - { 0x0C4E8086, "BWD Atom Processor S1200 Non-Transparent Bridge B2B", - NTB_ATOM, 0 }, - - { 0x37258086, "JSF Xeon C35xx/C55xx Non-Transparent Bridge B2B", - NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 }, - { 0x3C0D8086, "SNB Xeon E5/Core i7 Non-Transparent Bridge B2B", - NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 }, - { 0x0E0D8086, "IVT Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON, - NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | - NTB_SB01BASE_LOCKUP | NTB_BAR_SIZE_4K }, - { 0x2F0D8086, "HSX Xeon E5 V3 Non-Transparent Bridge B2B", NTB_XEON, - NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | - NTB_SB01BASE_LOCKUP }, - { 0x6F0D8086, "BDX Xeon E5 V4 Non-Transparent Bridge B2B", NTB_XEON, - NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | - NTB_SB01BASE_LOCKUP }, - - { 0x00000000, NULL, NTB_ATOM, 0 } -}; - -static const struct ntb_reg atom_reg = { - .ntb_ctl = ATOM_NTBCNTL_OFFSET, - .lnk_sta = ATOM_LINK_STATUS_OFFSET, - .db_size = sizeof(uint64_t), - .mw_bar = { NTB_B2B_BAR_1, NTB_B2B_BAR_2 }, -}; - -static const struct ntb_alt_reg atom_pri_reg = { - .db_bell = ATOM_PDOORBELL_OFFSET, - .db_mask = ATOM_PDBMSK_OFFSET, - .spad = ATOM_SPAD_OFFSET, -}; - -static const struct ntb_alt_reg atom_b2b_reg = { - .db_bell = ATOM_B2B_DOORBELL_OFFSET, - .spad = ATOM_B2B_SPAD_OFFSET, -}; - -static const struct ntb_xlat_reg atom_sec_xlat = { -#if 0 - /* "FIXME" says the Linux driver. */ - .bar0_base = ATOM_SBAR0BASE_OFFSET, - .bar2_base = ATOM_SBAR2BASE_OFFSET, - .bar4_base = ATOM_SBAR4BASE_OFFSET, - - .bar2_limit = ATOM_SBAR2LMT_OFFSET, - .bar4_limit = ATOM_SBAR4LMT_OFFSET, -#endif - - .bar2_xlat = ATOM_SBAR2XLAT_OFFSET, - .bar4_xlat = ATOM_SBAR4XLAT_OFFSET, -}; - -static const struct ntb_reg xeon_reg = { - .ntb_ctl = XEON_NTBCNTL_OFFSET, - .lnk_sta = XEON_LINK_STATUS_OFFSET, - .db_size = sizeof(uint16_t), - .mw_bar = { NTB_B2B_BAR_1, NTB_B2B_BAR_2, NTB_B2B_BAR_3 }, -}; - -static const struct ntb_alt_reg xeon_pri_reg = { - .db_bell = XEON_PDOORBELL_OFFSET, - .db_mask = XEON_PDBMSK_OFFSET, - .spad = XEON_SPAD_OFFSET, -}; - -static const struct ntb_alt_reg xeon_b2b_reg = { - .db_bell = XEON_B2B_DOORBELL_OFFSET, - .spad = XEON_B2B_SPAD_OFFSET, -}; - -static const struct ntb_xlat_reg xeon_sec_xlat = { - .bar0_base = XEON_SBAR0BASE_OFFSET, - .bar2_base = XEON_SBAR2BASE_OFFSET, - .bar4_base = XEON_SBAR4BASE_OFFSET, - .bar5_base = XEON_SBAR5BASE_OFFSET, - - .bar2_limit = XEON_SBAR2LMT_OFFSET, - .bar4_limit = XEON_SBAR4LMT_OFFSET, - .bar5_limit = XEON_SBAR5LMT_OFFSET, - - .bar2_xlat = XEON_SBAR2XLAT_OFFSET, - .bar4_xlat = XEON_SBAR4XLAT_OFFSET, - .bar5_xlat = XEON_SBAR5XLAT_OFFSET, -}; - -static struct ntb_b2b_addr xeon_b2b_usd_addr = { - .bar0_addr = XEON_B2B_BAR0_ADDR, - .bar2_addr64 = XEON_B2B_BAR2_ADDR64, - .bar4_addr64 = XEON_B2B_BAR4_ADDR64, - .bar4_addr32 = XEON_B2B_BAR4_ADDR32, - .bar5_addr32 = XEON_B2B_BAR5_ADDR32, -}; - -static struct ntb_b2b_addr xeon_b2b_dsd_addr = { - .bar0_addr = XEON_B2B_BAR0_ADDR, - .bar2_addr64 = XEON_B2B_BAR2_ADDR64, - .bar4_addr64 = XEON_B2B_BAR4_ADDR64, - .bar4_addr32 = XEON_B2B_BAR4_ADDR32, - .bar5_addr32 = XEON_B2B_BAR5_ADDR32, -}; - -SYSCTL_NODE(_hw_ntb, OID_AUTO, xeon_b2b, CTLFLAG_RW, 0, - "B2B MW segment overrides -- MUST be the same on both sides"); - -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar2_addr64, CTLFLAG_RDTUN, - &xeon_b2b_usd_addr.bar2_addr64, 0, "If using B2B topology on Xeon " - "hardware, use this 64-bit address on the bus between the NTB devices for " - "the window at BAR2, on the upstream side of the link. MUST be the same " - "address on both sides."); -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar4_addr64, CTLFLAG_RDTUN, - &xeon_b2b_usd_addr.bar4_addr64, 0, "See usd_bar2_addr64, but BAR4."); -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar4_addr32, CTLFLAG_RDTUN, - &xeon_b2b_usd_addr.bar4_addr32, 0, "See usd_bar2_addr64, but BAR4 " - "(split-BAR mode)."); -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar5_addr32, CTLFLAG_RDTUN, - &xeon_b2b_usd_addr.bar5_addr32, 0, "See usd_bar2_addr64, but BAR5 " - "(split-BAR mode)."); - -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar2_addr64, CTLFLAG_RDTUN, - &xeon_b2b_dsd_addr.bar2_addr64, 0, "If using B2B topology on Xeon " - "hardware, use this 64-bit address on the bus between the NTB devices for " - "the window at BAR2, on the downstream side of the link. MUST be the same" - " address on both sides."); -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar4_addr64, CTLFLAG_RDTUN, - &xeon_b2b_dsd_addr.bar4_addr64, 0, "See dsd_bar2_addr64, but BAR4."); -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar4_addr32, CTLFLAG_RDTUN, - &xeon_b2b_dsd_addr.bar4_addr32, 0, "See dsd_bar2_addr64, but BAR4 " - "(split-BAR mode)."); -SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar5_addr32, CTLFLAG_RDTUN, - &xeon_b2b_dsd_addr.bar5_addr32, 0, "See dsd_bar2_addr64, but BAR5 " - "(split-BAR mode)."); - -/* - * OS <-> Driver interface structures - */ -MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations"); - -/* - * OS <-> Driver linkage functions - */ -static int -intel_ntb_probe(device_t device) -{ - struct ntb_hw_info *p; - - p = intel_ntb_get_device_info(pci_get_devid(device)); - if (p == NULL) - return (ENXIO); - - device_set_desc(device, p->desc); - return (0); -} - -static int -intel_ntb_attach(device_t device) -{ - struct ntb_softc *ntb; - struct ntb_hw_info *p; - int error; - - ntb = device_get_softc(device); - p = intel_ntb_get_device_info(pci_get_devid(device)); - - ntb->device = device; - ntb->type = p->type; - ntb->features = p->features; - ntb->b2b_mw_idx = B2B_MW_DISABLED; - ntb->msix_mw_idx = B2B_MW_DISABLED; - - /* Heartbeat timer for NTB_ATOM since there is no link interrupt */ - callout_init(&ntb->heartbeat_timer, 1); - callout_init(&ntb->lr_timer, 1); - callout_init(&ntb->peer_msix_work, 1); - mtx_init(&ntb->db_mask_lock, "ntb hw bits", NULL, MTX_SPIN); - - if (ntb->type == NTB_ATOM) - error = intel_ntb_detect_atom(ntb); - else - error = intel_ntb_detect_xeon(ntb); - if (error != 0) - goto out; - - intel_ntb_detect_max_mw(ntb); - - pci_enable_busmaster(ntb->device); - - error = intel_ntb_map_pci_bars(ntb); - if (error != 0) - goto out; - if (ntb->type == NTB_ATOM) - error = intel_ntb_atom_init_dev(ntb); - else - error = intel_ntb_xeon_init_dev(ntb); - if (error != 0) - goto out; - - intel_ntb_spad_clear(device); - - intel_ntb_poll_link(ntb); - - intel_ntb_sysctl_init(ntb); - - /* Attach children to this controller */ - error = ntb_register_device(device); - -out: - if (error != 0) - intel_ntb_detach(device); - return (error); -} - -static int -intel_ntb_detach(device_t device) -{ - struct ntb_softc *ntb; - - ntb = device_get_softc(device); - - /* Detach & delete all children */ - ntb_unregister_device(device); - - if (ntb->self_reg != NULL) { - DB_MASK_LOCK(ntb); - db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_valid_mask); - DB_MASK_UNLOCK(ntb); - } - callout_drain(&ntb->heartbeat_timer); - callout_drain(&ntb->lr_timer); - callout_drain(&ntb->peer_msix_work); - pci_disable_busmaster(ntb->device); - if (ntb->type == NTB_XEON) - intel_ntb_teardown_xeon(ntb); - intel_ntb_teardown_interrupts(ntb); - - mtx_destroy(&ntb->db_mask_lock); - - intel_ntb_unmap_pci_bar(ntb); - - return (0); -} - -/* - * Driver internal routines - */ -static inline enum ntb_bar -intel_ntb_mw_to_bar(struct ntb_softc *ntb, unsigned mw) -{ - - KASSERT(mw < ntb->mw_count, - ("%s: mw:%u > count:%u", __func__, mw, (unsigned)ntb->mw_count)); - KASSERT(ntb->reg->mw_bar[mw] != 0, ("invalid mw")); - - return (ntb->reg->mw_bar[mw]); -} - -static inline bool -bar_is_64bit(struct ntb_softc *ntb, enum ntb_bar bar) -{ - /* XXX This assertion could be stronger. */ - KASSERT(bar < NTB_MAX_BARS, ("bogus bar")); - return (bar < NTB_B2B_BAR_2 || !HAS_FEATURE(ntb, NTB_SPLIT_BAR)); -} - -static inline void -bar_get_xlat_params(struct ntb_softc *ntb, enum ntb_bar bar, uint32_t *base, - uint32_t *xlat, uint32_t *lmt) -{ - uint32_t basev, lmtv, xlatv; - - switch (bar) { - case NTB_B2B_BAR_1: - basev = ntb->xlat_reg->bar2_base; - lmtv = ntb->xlat_reg->bar2_limit; - xlatv = ntb->xlat_reg->bar2_xlat; - break; - case NTB_B2B_BAR_2: - basev = ntb->xlat_reg->bar4_base; - lmtv = ntb->xlat_reg->bar4_limit; - xlatv = ntb->xlat_reg->bar4_xlat; - break; - case NTB_B2B_BAR_3: - basev = ntb->xlat_reg->bar5_base; - lmtv = ntb->xlat_reg->bar5_limit; - xlatv = ntb->xlat_reg->bar5_xlat; - break; - default: - KASSERT(bar >= NTB_B2B_BAR_1 && bar < NTB_MAX_BARS, - ("bad bar")); - basev = lmtv = xlatv = 0; - break; - } - - if (base != NULL) - *base = basev; - if (xlat != NULL) - *xlat = xlatv; - if (lmt != NULL) - *lmt = lmtv; -} - -static int -intel_ntb_map_pci_bars(struct ntb_softc *ntb) -{ - int rc; - - ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0); - rc = map_mmr_bar(ntb, &ntb->bar_info[NTB_CONFIG_BAR]); - if (rc != 0) - goto out; - - ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2); - rc = map_memory_window_bar(ntb, &ntb->bar_info[NTB_B2B_BAR_1]); - if (rc != 0) - goto out; - ntb->bar_info[NTB_B2B_BAR_1].psz_off = XEON_PBAR23SZ_OFFSET; - ntb->bar_info[NTB_B2B_BAR_1].ssz_off = XEON_SBAR23SZ_OFFSET; - ntb->bar_info[NTB_B2B_BAR_1].pbarxlat_off = XEON_PBAR2XLAT_OFFSET; - - ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4); - rc = map_memory_window_bar(ntb, &ntb->bar_info[NTB_B2B_BAR_2]); - if (rc != 0) - goto out; - ntb->bar_info[NTB_B2B_BAR_2].psz_off = XEON_PBAR4SZ_OFFSET; - ntb->bar_info[NTB_B2B_BAR_2].ssz_off = XEON_SBAR4SZ_OFFSET; - ntb->bar_info[NTB_B2B_BAR_2].pbarxlat_off = XEON_PBAR4XLAT_OFFSET; - - if (!HAS_FEATURE(ntb, NTB_SPLIT_BAR)) - goto out; - - ntb->bar_info[NTB_B2B_BAR_3].pci_resource_id = PCIR_BAR(5); - rc = map_memory_window_bar(ntb, &ntb->bar_info[NTB_B2B_BAR_3]); - ntb->bar_info[NTB_B2B_BAR_3].psz_off = XEON_PBAR5SZ_OFFSET; - ntb->bar_info[NTB_B2B_BAR_3].ssz_off = XEON_SBAR5SZ_OFFSET; - ntb->bar_info[NTB_B2B_BAR_3].pbarxlat_off = XEON_PBAR5XLAT_OFFSET; - -out: - if (rc != 0) - device_printf(ntb->device, - "unable to allocate pci resource\n"); - return (rc); -} - -static void -print_map_success(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar, - const char *kind) -{ - - device_printf(ntb->device, - "Mapped BAR%d v:[%p-%p] p:[%p-%p] (0x%jx bytes) (%s)\n", - PCI_RID2BAR(bar->pci_resource_id), bar->vbase, - (char *)bar->vbase + bar->size - 1, - (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), - (uintmax_t)bar->size, kind); -} - -static int -map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) -{ - - bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, - &bar->pci_resource_id, RF_ACTIVE); - if (bar->pci_resource == NULL) - return (ENXIO); - - save_bar_parameters(bar); - bar->map_mode = VM_MEMATTR_UNCACHEABLE; - print_map_success(ntb, bar, "mmr"); - return (0); -} - -static int -map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) -{ - int rc; - vm_memattr_t mapmode; - uint8_t bar_size_bits = 0; - - bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, - &bar->pci_resource_id, RF_ACTIVE); - - if (bar->pci_resource == NULL) - return (ENXIO); - - save_bar_parameters(bar); - /* - * Ivytown NTB BAR sizes are misreported by the hardware due to a - * hardware issue. To work around this, query the size it should be - * configured to by the device and modify the resource to correspond to - * this new size. The BIOS on systems with this problem is required to - * provide enough address space to allow the driver to make this change - * safely. - * - * Ideally I could have just specified the size when I allocated the - * resource like: - * bus_alloc_resource(ntb->device, - * SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul, - * 1ul << bar_size_bits, RF_ACTIVE); - * but the PCI driver does not honor the size in this call, so we have - * to modify it after the fact. - */ - if (HAS_FEATURE(ntb, NTB_BAR_SIZE_4K)) { - if (bar->pci_resource_id == PCIR_BAR(2)) - bar_size_bits = pci_read_config(ntb->device, - XEON_PBAR23SZ_OFFSET, 1); - else - bar_size_bits = pci_read_config(ntb->device, - XEON_PBAR45SZ_OFFSET, 1); - - rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY, - bar->pci_resource, bar->pbase, - bar->pbase + (1ul << bar_size_bits) - 1); - if (rc != 0) { - device_printf(ntb->device, - "unable to resize bar\n"); - return (rc); - } - - save_bar_parameters(bar); - } - - bar->map_mode = VM_MEMATTR_UNCACHEABLE; - print_map_success(ntb, bar, "mw"); - - /* - * Optionally, mark MW BARs as anything other than UC to improve - * performance. - */ - mapmode = intel_ntb_pat_flags(); - if (mapmode == bar->map_mode) - return (0); - - rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mapmode); - if (rc == 0) { - bar->map_mode = mapmode; - device_printf(ntb->device, - "Marked BAR%d v:[%p-%p] p:[%p-%p] as " - "%s.\n", - PCI_RID2BAR(bar->pci_resource_id), bar->vbase, - (char *)bar->vbase + bar->size - 1, - (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), - intel_ntb_vm_memattr_to_str(mapmode)); - } else - device_printf(ntb->device, - "Unable to mark BAR%d v:[%p-%p] p:[%p-%p] as " - "%s: %d\n", - PCI_RID2BAR(bar->pci_resource_id), bar->vbase, - (char *)bar->vbase + bar->size - 1, - (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), - intel_ntb_vm_memattr_to_str(mapmode), rc); - /* Proceed anyway */ - return (0); -} - -static void -intel_ntb_unmap_pci_bar(struct ntb_softc *ntb) -{ - struct ntb_pci_bar_info *current_bar; - int i; - - for (i = 0; i < NTB_MAX_BARS; i++) { - current_bar = &ntb->bar_info[i]; - if (current_bar->pci_resource != NULL) - bus_release_resource(ntb->device, SYS_RES_MEMORY, - current_bar->pci_resource_id, - current_bar->pci_resource); - } -} - -static int -intel_ntb_setup_msix(struct ntb_softc *ntb, uint32_t num_vectors) -{ - uint32_t i; - int rc; - - for (i = 0; i < num_vectors; i++) { - ntb->int_info[i].rid = i + 1; - ntb->int_info[i].res = bus_alloc_resource_any(ntb->device, - SYS_RES_IRQ, &ntb->int_info[i].rid, RF_ACTIVE); - if (ntb->int_info[i].res == NULL) { - device_printf(ntb->device, - "bus_alloc_resource failed\n"); - return (ENOMEM); - } - ntb->int_info[i].tag = NULL; - ntb->allocated_interrupts++; - rc = bus_setup_intr(ntb->device, ntb->int_info[i].res, - INTR_MPSAFE | INTR_TYPE_MISC, NULL, ndev_vec_isr, - &ntb->msix_vec[i], &ntb->int_info[i].tag); - if (rc != 0) { - device_printf(ntb->device, "bus_setup_intr failed\n"); - return (ENXIO); - } - } - return (0); -} - -/* - * The Linux NTB driver drops from MSI-X to legacy INTx if a unique vector - * cannot be allocated for each MSI-X message. JHB seems to think remapping - * should be okay. This tunable should enable us to test that hypothesis - * when someone gets their hands on some Xeon hardware. - */ -static int ntb_force_remap_mode; -SYSCTL_INT(_hw_ntb, OID_AUTO, force_remap_mode, CTLFLAG_RDTUN, - &ntb_force_remap_mode, 0, "If enabled, force MSI-X messages to be remapped" - " to a smaller number of ithreads, even if the desired number are " - "available"); - -/* - * In case it is NOT ok, give consumers an abort button. - */ -static int ntb_prefer_intx; -SYSCTL_INT(_hw_ntb, OID_AUTO, prefer_intx_to_remap, CTLFLAG_RDTUN, - &ntb_prefer_intx, 0, "If enabled, prefer to use legacy INTx mode rather " - "than remapping MSI-X messages over available slots (match Linux driver " - "behavior)"); - -/* - * Remap the desired number of MSI-X messages to available ithreads in a simple - * round-robin fashion. - */ -static int -intel_ntb_remap_msix(device_t dev, uint32_t desired, uint32_t avail) -{ - u_int *vectors; - uint32_t i; - int rc; - - if (ntb_prefer_intx != 0) - return (ENXIO); - - vectors = malloc(desired * sizeof(*vectors), M_NTB, M_ZERO | M_WAITOK); - - for (i = 0; i < desired; i++) - vectors[i] = (i % avail) + 1; - - rc = pci_remap_msix(dev, desired, vectors); - free(vectors, M_NTB); - return (rc); -} - -static int -intel_ntb_init_isr(struct ntb_softc *ntb) -{ - uint32_t desired_vectors, num_vectors; - int rc; - - ntb->allocated_interrupts = 0; - ntb->last_ts = ticks; - - /* - * Mask all doorbell interrupts. (Except link events!) - */ - DB_MASK_LOCK(ntb); - ntb->db_mask = ntb->db_valid_mask; - db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); - DB_MASK_UNLOCK(ntb); - - num_vectors = desired_vectors = MIN(pci_msix_count(ntb->device), - ntb->db_count); - if (desired_vectors >= 1) { - rc = pci_alloc_msix(ntb->device, &num_vectors); - - if (ntb_force_remap_mode != 0 && rc == 0 && - num_vectors == desired_vectors) - num_vectors--; - - if (rc == 0 && num_vectors < desired_vectors) { - rc = intel_ntb_remap_msix(ntb->device, desired_vectors, - num_vectors); - if (rc == 0) - num_vectors = desired_vectors; - else - pci_release_msi(ntb->device); - } - if (rc != 0) - num_vectors = 1; - } else - num_vectors = 1; - - if (ntb->type == NTB_XEON && num_vectors < ntb->db_vec_count) { - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - device_printf(ntb->device, - "Errata workaround does not support MSI or INTX\n"); - return (EINVAL); - } - - ntb->db_vec_count = 1; - ntb->db_vec_shift = XEON_DB_TOTAL_SHIFT; - rc = intel_ntb_setup_legacy_interrupt(ntb); - } else { - if (num_vectors - 1 != XEON_NONLINK_DB_MSIX_BITS && - HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - device_printf(ntb->device, - "Errata workaround expects %d doorbell bits\n", - XEON_NONLINK_DB_MSIX_BITS); - return (EINVAL); - } - - intel_ntb_create_msix_vec(ntb, num_vectors); - rc = intel_ntb_setup_msix(ntb, num_vectors); - } - if (rc != 0) { - device_printf(ntb->device, - "Error allocating interrupts: %d\n", rc); - intel_ntb_free_msix_vec(ntb); - } - - return (rc); -} - -static int -intel_ntb_setup_legacy_interrupt(struct ntb_softc *ntb) -{ - int rc; - - ntb->int_info[0].rid = 0; - ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ, - &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); - if (ntb->int_info[0].res == NULL) { - device_printf(ntb->device, "bus_alloc_resource failed\n"); - return (ENOMEM); - } - - ntb->int_info[0].tag = NULL; - ntb->allocated_interrupts = 1; - - rc = bus_setup_intr(ntb->device, ntb->int_info[0].res, - INTR_MPSAFE | INTR_TYPE_MISC, NULL, ndev_irq_isr, - ntb, &ntb->int_info[0].tag); - if (rc != 0) { - device_printf(ntb->device, "bus_setup_intr failed\n"); - return (ENXIO); - } - - return (0); -} - -static void -intel_ntb_teardown_interrupts(struct ntb_softc *ntb) -{ - struct ntb_int_info *current_int; - int i; - - for (i = 0; i < ntb->allocated_interrupts; i++) { - current_int = &ntb->int_info[i]; - if (current_int->tag != NULL) - bus_teardown_intr(ntb->device, current_int->res, - current_int->tag); - - if (current_int->res != NULL) - bus_release_resource(ntb->device, SYS_RES_IRQ, - rman_get_rid(current_int->res), current_int->res); - } - - intel_ntb_free_msix_vec(ntb); - pci_release_msi(ntb->device); -} - -/* - * Doorbell register and mask are 64-bit on Atom, 16-bit on Xeon. Abstract it - * out to make code clearer. - */ -static inline uint64_t -db_ioread(struct ntb_softc *ntb, uint64_t regoff) -{ - - if (ntb->type == NTB_ATOM) - return (intel_ntb_reg_read(8, regoff)); - - KASSERT(ntb->type == NTB_XEON, ("bad ntb type")); - - return (intel_ntb_reg_read(2, regoff)); -} - -static inline void -db_iowrite(struct ntb_softc *ntb, uint64_t regoff, uint64_t val) -{ - - KASSERT((val & ~ntb->db_valid_mask) == 0, - ("%s: Invalid bits 0x%jx (valid: 0x%jx)", __func__, - (uintmax_t)(val & ~ntb->db_valid_mask), - (uintmax_t)ntb->db_valid_mask)); - - if (regoff == ntb->self_reg->db_mask) - DB_MASK_ASSERT(ntb, MA_OWNED); - db_iowrite_raw(ntb, regoff, val); -} - -static inline void -db_iowrite_raw(struct ntb_softc *ntb, uint64_t regoff, uint64_t val) -{ - - if (ntb->type == NTB_ATOM) { - intel_ntb_reg_write(8, regoff, val); - return; - } - - KASSERT(ntb->type == NTB_XEON, ("bad ntb type")); - intel_ntb_reg_write(2, regoff, (uint16_t)val); -} - -static void -intel_ntb_db_set_mask(device_t dev, uint64_t bits) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - DB_MASK_LOCK(ntb); - ntb->db_mask |= bits; - if (!HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) - db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); - DB_MASK_UNLOCK(ntb); -} - -static void -intel_ntb_db_clear_mask(device_t dev, uint64_t bits) -{ - struct ntb_softc *ntb = device_get_softc(dev); - uint64_t ibits; - int i; - - KASSERT((bits & ~ntb->db_valid_mask) == 0, - ("%s: Invalid bits 0x%jx (valid: 0x%jx)", __func__, - (uintmax_t)(bits & ~ntb->db_valid_mask), - (uintmax_t)ntb->db_valid_mask)); - - DB_MASK_LOCK(ntb); - ibits = ntb->fake_db & ntb->db_mask & bits; - ntb->db_mask &= ~bits; - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - /* Simulate fake interrupts if unmasked DB bits are set. */ - ntb->force_db |= ibits; - for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { - if ((ibits & intel_ntb_db_vector_mask(dev, i)) != 0) - swi_sched(ntb->int_info[i].tag, 0); - } - } else { - db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); - } - DB_MASK_UNLOCK(ntb); -} - -static uint64_t -intel_ntb_db_read(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) - return (ntb->fake_db); - - return (db_ioread(ntb, ntb->self_reg->db_bell)); -} - -static void -intel_ntb_db_clear(device_t dev, uint64_t bits) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - KASSERT((bits & ~ntb->db_valid_mask) == 0, - ("%s: Invalid bits 0x%jx (valid: 0x%jx)", __func__, - (uintmax_t)(bits & ~ntb->db_valid_mask), - (uintmax_t)ntb->db_valid_mask)); - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - DB_MASK_LOCK(ntb); - ntb->fake_db &= ~bits; - DB_MASK_UNLOCK(ntb); - return; - } - - db_iowrite(ntb, ntb->self_reg->db_bell, bits); -} - -static inline uint64_t -intel_ntb_vec_mask(struct ntb_softc *ntb, uint64_t db_vector) -{ - uint64_t shift, mask; - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - /* - * Remap vectors in custom way to make at least first - * three doorbells to not generate stray events. - * This breaks Linux compatibility (if one existed) - * when more then one DB is used (not by if_ntb). - */ - if (db_vector < XEON_NONLINK_DB_MSIX_BITS - 1) - return (1 << db_vector); - if (db_vector == XEON_NONLINK_DB_MSIX_BITS - 1) - return (0x7ffc); - } - - shift = ntb->db_vec_shift; - mask = (1ull << shift) - 1; - return (mask << (shift * db_vector)); -} - -static void -intel_ntb_interrupt(struct ntb_softc *ntb, uint32_t vec) -{ - uint64_t vec_mask; - - ntb->last_ts = ticks; - vec_mask = intel_ntb_vec_mask(ntb, vec); - - if ((vec_mask & ntb->db_link_mask) != 0) { - if (intel_ntb_poll_link(ntb)) - ntb_link_event(ntb->device); - } - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP) && - (vec_mask & ntb->db_link_mask) == 0) { - DB_MASK_LOCK(ntb); - - /* - * Do not report same DB events again if not cleared yet, - * unless the mask was just cleared for them and this - * interrupt handler call can be the consequence of it. - */ - vec_mask &= ~ntb->fake_db | ntb->force_db; - ntb->force_db &= ~vec_mask; - - /* Update our internal doorbell register. */ - ntb->fake_db |= vec_mask; - - /* Do not report masked DB events. */ - vec_mask &= ~ntb->db_mask; - - DB_MASK_UNLOCK(ntb); - } - - if ((vec_mask & ntb->db_valid_mask) != 0) - ntb_db_event(ntb->device, vec); -} - -static void -ndev_vec_isr(void *arg) -{ - struct ntb_vec *nvec = arg; - - intel_ntb_interrupt(nvec->ntb, nvec->num); -} - -static void -ndev_irq_isr(void *arg) -{ - /* If we couldn't set up MSI-X, we only have the one vector. */ - intel_ntb_interrupt(arg, 0); -} - -static int -intel_ntb_create_msix_vec(struct ntb_softc *ntb, uint32_t num_vectors) -{ - uint32_t i; - - ntb->msix_vec = malloc(num_vectors * sizeof(*ntb->msix_vec), M_NTB, - M_ZERO | M_WAITOK); - for (i = 0; i < num_vectors; i++) { - ntb->msix_vec[i].num = i; - ntb->msix_vec[i].ntb = ntb; - } - - return (0); -} - -static void -intel_ntb_free_msix_vec(struct ntb_softc *ntb) -{ - - if (ntb->msix_vec == NULL) - return; - - free(ntb->msix_vec, M_NTB); - ntb->msix_vec = NULL; -} - -static void -intel_ntb_get_msix_info(struct ntb_softc *ntb) -{ - struct pci_devinfo *dinfo; - struct pcicfg_msix *msix; - uint32_t laddr, data, i, offset; - - dinfo = device_get_ivars(ntb->device); - msix = &dinfo->cfg.msix; - - CTASSERT(XEON_NONLINK_DB_MSIX_BITS == nitems(ntb->msix_data)); - - for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { - offset = msix->msix_table_offset + i * PCI_MSIX_ENTRY_SIZE; - - laddr = bus_read_4(msix->msix_table_res, offset + - PCI_MSIX_ENTRY_LOWER_ADDR); - intel_ntb_printf(2, "local MSIX addr(%u): 0x%x\n", i, laddr); - - KASSERT((laddr & MSI_INTEL_ADDR_BASE) == MSI_INTEL_ADDR_BASE, - ("local MSIX addr 0x%x not in MSI base 0x%x", laddr, - MSI_INTEL_ADDR_BASE)); - ntb->msix_data[i].nmd_ofs = laddr; - - data = bus_read_4(msix->msix_table_res, offset + - PCI_MSIX_ENTRY_DATA); - intel_ntb_printf(2, "local MSIX data(%u): 0x%x\n", i, data); - - ntb->msix_data[i].nmd_data = data; - } -} - -static struct ntb_hw_info * -intel_ntb_get_device_info(uint32_t device_id) -{ - struct ntb_hw_info *ep = pci_ids; - - while (ep->device_id) { - if (ep->device_id == device_id) - return (ep); - ++ep; - } - return (NULL); -} - -static void -intel_ntb_teardown_xeon(struct ntb_softc *ntb) -{ - - if (ntb->reg != NULL) - intel_ntb_link_disable(ntb->device); -} - -static void -intel_ntb_detect_max_mw(struct ntb_softc *ntb) -{ - - if (ntb->type == NTB_ATOM) { - ntb->mw_count = ATOM_MW_COUNT; - return; - } - - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) - ntb->mw_count = XEON_HSX_SPLIT_MW_COUNT; - else - ntb->mw_count = XEON_SNB_MW_COUNT; -} - -static int -intel_ntb_detect_xeon(struct ntb_softc *ntb) -{ - uint8_t ppd, conn_type; - - ppd = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1); - ntb->ppd = ppd; - - if ((ppd & XEON_PPD_DEV_TYPE) != 0) - ntb->dev_type = NTB_DEV_DSD; - else - ntb->dev_type = NTB_DEV_USD; - - if ((ppd & XEON_PPD_SPLIT_BAR) != 0) - ntb->features |= NTB_SPLIT_BAR; - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP) && - !HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - device_printf(ntb->device, - "Can not apply SB01BASE_LOCKUP workaround " - "with split BARs disabled!\n"); - device_printf(ntb->device, - "Expect system hangs under heavy NTB traffic!\n"); - ntb->features &= ~NTB_SB01BASE_LOCKUP; - } - - /* - * SDOORBELL errata workaround gets in the way of SB01BASE_LOCKUP - * errata workaround; only do one at a time. - */ - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) - ntb->features &= ~NTB_SDOORBELL_LOCKUP; - - conn_type = ppd & XEON_PPD_CONN_TYPE; - switch (conn_type) { - case NTB_CONN_B2B: - ntb->conn_type = conn_type; - break; - case NTB_CONN_RP: - case NTB_CONN_TRANSPARENT: - default: - device_printf(ntb->device, "Unsupported connection type: %u\n", - (unsigned)conn_type); - return (ENXIO); - } - return (0); -} - -static int -intel_ntb_detect_atom(struct ntb_softc *ntb) -{ - uint32_t ppd, conn_type; - - ppd = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4); - ntb->ppd = ppd; - - if ((ppd & ATOM_PPD_DEV_TYPE) != 0) - ntb->dev_type = NTB_DEV_DSD; - else - ntb->dev_type = NTB_DEV_USD; - - conn_type = (ppd & ATOM_PPD_CONN_TYPE) >> 8; - switch (conn_type) { - case NTB_CONN_B2B: - ntb->conn_type = conn_type; - break; - default: - device_printf(ntb->device, "Unsupported NTB configuration\n"); - return (ENXIO); - } - return (0); -} - -static int -intel_ntb_xeon_init_dev(struct ntb_softc *ntb) -{ - int rc; - - ntb->spad_count = XEON_SPAD_COUNT; - ntb->db_count = XEON_DB_COUNT; - ntb->db_link_mask = XEON_DB_LINK_BIT; - ntb->db_vec_count = XEON_DB_MSIX_VECTOR_COUNT; - ntb->db_vec_shift = XEON_DB_MSIX_VECTOR_SHIFT; - - if (ntb->conn_type != NTB_CONN_B2B) { - device_printf(ntb->device, "Connection type %d not supported\n", - ntb->conn_type); - return (ENXIO); - } - - ntb->reg = &xeon_reg; - ntb->self_reg = &xeon_pri_reg; - ntb->peer_reg = &xeon_b2b_reg; - ntb->xlat_reg = &xeon_sec_xlat; - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - ntb->force_db = ntb->fake_db = 0; - ntb->msix_mw_idx = (ntb->mw_count + g_ntb_msix_idx) % - ntb->mw_count; - intel_ntb_printf(2, "Setting up MSIX mw idx %d means %u\n", - g_ntb_msix_idx, ntb->msix_mw_idx); - rc = intel_ntb_mw_set_wc_internal(ntb, ntb->msix_mw_idx, - VM_MEMATTR_UNCACHEABLE); - KASSERT(rc == 0, ("shouldn't fail")); - } else if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) { - /* - * There is a Xeon hardware errata related to writes to SDOORBELL or - * B2BDOORBELL in conjunction with inbound access to NTB MMIO space, - * which may hang the system. To workaround this, use a memory - * window to access the interrupt and scratch pad registers on the - * remote system. - */ - ntb->b2b_mw_idx = (ntb->mw_count + g_ntb_mw_idx) % - ntb->mw_count; - intel_ntb_printf(2, "Setting up b2b mw idx %d means %u\n", - g_ntb_mw_idx, ntb->b2b_mw_idx); - rc = intel_ntb_mw_set_wc_internal(ntb, ntb->b2b_mw_idx, - VM_MEMATTR_UNCACHEABLE); - KASSERT(rc == 0, ("shouldn't fail")); - } else if (HAS_FEATURE(ntb, NTB_B2BDOORBELL_BIT14)) - /* - * HW Errata on bit 14 of b2bdoorbell register. Writes will not be - * mirrored to the remote system. Shrink the number of bits by one, - * since bit 14 is the last bit. - * - * On REGS_THRU_MW errata mode, we don't use the b2bdoorbell register - * anyway. Nor for non-B2B connection types. - */ - ntb->db_count = XEON_DB_COUNT - 1; - - ntb->db_valid_mask = (1ull << ntb->db_count) - 1; - - if (ntb->dev_type == NTB_DEV_USD) - rc = xeon_setup_b2b_mw(ntb, &xeon_b2b_dsd_addr, - &xeon_b2b_usd_addr); - else - rc = xeon_setup_b2b_mw(ntb, &xeon_b2b_usd_addr, - &xeon_b2b_dsd_addr); - if (rc != 0) - return (rc); - - /* Enable Bus Master and Memory Space on the secondary side */ - intel_ntb_reg_write(2, XEON_SPCICMD_OFFSET, - PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); - - /* - * Mask all doorbell interrupts. - */ - DB_MASK_LOCK(ntb); - ntb->db_mask = ntb->db_valid_mask; - db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); - DB_MASK_UNLOCK(ntb); - - rc = intel_ntb_init_isr(ntb); - return (rc); -} - -static int -intel_ntb_atom_init_dev(struct ntb_softc *ntb) -{ - int error; - - KASSERT(ntb->conn_type == NTB_CONN_B2B, - ("Unsupported NTB configuration (%d)\n", ntb->conn_type)); - - ntb->spad_count = ATOM_SPAD_COUNT; - ntb->db_count = ATOM_DB_COUNT; - ntb->db_vec_count = ATOM_DB_MSIX_VECTOR_COUNT; - ntb->db_vec_shift = ATOM_DB_MSIX_VECTOR_SHIFT; - ntb->db_valid_mask = (1ull << ntb->db_count) - 1; - - ntb->reg = &atom_reg; - ntb->self_reg = &atom_pri_reg; - ntb->peer_reg = &atom_b2b_reg; - ntb->xlat_reg = &atom_sec_xlat; - - /* - * FIXME - MSI-X bug on early Atom HW, remove once internal issue is - * resolved. Mask transaction layer internal parity errors. - */ - pci_write_config(ntb->device, 0xFC, 0x4, 4); - - configure_atom_secondary_side_bars(ntb); - - /* Enable Bus Master and Memory Space on the secondary side */ - intel_ntb_reg_write(2, ATOM_SPCICMD_OFFSET, - PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); - - error = intel_ntb_init_isr(ntb); - if (error != 0) - return (error); - - /* Initiate PCI-E link training */ - intel_ntb_link_enable(ntb->device, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); - - callout_reset(&ntb->heartbeat_timer, 0, atom_link_hb, ntb); - - return (0); -} - -/* XXX: Linux driver doesn't seem to do any of this for Atom. */ -static void -configure_atom_secondary_side_bars(struct ntb_softc *ntb) -{ - - if (ntb->dev_type == NTB_DEV_USD) { - intel_ntb_reg_write(8, ATOM_PBAR2XLAT_OFFSET, - XEON_B2B_BAR2_ADDR64); - intel_ntb_reg_write(8, ATOM_PBAR4XLAT_OFFSET, - XEON_B2B_BAR4_ADDR64); - intel_ntb_reg_write(8, ATOM_MBAR23_OFFSET, XEON_B2B_BAR2_ADDR64); - intel_ntb_reg_write(8, ATOM_MBAR45_OFFSET, XEON_B2B_BAR4_ADDR64); - } else { - intel_ntb_reg_write(8, ATOM_PBAR2XLAT_OFFSET, - XEON_B2B_BAR2_ADDR64); - intel_ntb_reg_write(8, ATOM_PBAR4XLAT_OFFSET, - XEON_B2B_BAR4_ADDR64); - intel_ntb_reg_write(8, ATOM_MBAR23_OFFSET, XEON_B2B_BAR2_ADDR64); - intel_ntb_reg_write(8, ATOM_MBAR45_OFFSET, XEON_B2B_BAR4_ADDR64); - } -} - - -/* - * When working around Xeon SDOORBELL errata by remapping remote registers in a - * MW, limit the B2B MW to half a MW. By sharing a MW, half the shared MW - * remains for use by a higher layer. - * - * Will only be used if working around SDOORBELL errata and the BIOS-configured - * MW size is sufficiently large. - */ -static unsigned int ntb_b2b_mw_share; -SYSCTL_UINT(_hw_ntb, OID_AUTO, b2b_mw_share, CTLFLAG_RDTUN, &ntb_b2b_mw_share, - 0, "If enabled (non-zero), prefer to share half of the B2B peer register " - "MW with higher level consumers. Both sides of the NTB MUST set the same " - "value here."); - -static void -xeon_reset_sbar_size(struct ntb_softc *ntb, enum ntb_bar idx, - enum ntb_bar regbar) -{ - struct ntb_pci_bar_info *bar; - uint8_t bar_sz; - - if (!HAS_FEATURE(ntb, NTB_SPLIT_BAR) && idx >= NTB_B2B_BAR_3) - return; - - bar = &ntb->bar_info[idx]; - bar_sz = pci_read_config(ntb->device, bar->psz_off, 1); - if (idx == regbar) { - if (ntb->b2b_off != 0) - bar_sz--; - else - bar_sz = 0; - } - pci_write_config(ntb->device, bar->ssz_off, bar_sz, 1); - bar_sz = pci_read_config(ntb->device, bar->ssz_off, 1); - (void)bar_sz; -} - -static void -xeon_set_sbar_base_and_limit(struct ntb_softc *ntb, uint64_t bar_addr, - enum ntb_bar idx, enum ntb_bar regbar) -{ - uint64_t reg_val; - uint32_t base_reg, lmt_reg; - - bar_get_xlat_params(ntb, idx, &base_reg, NULL, &lmt_reg); - if (idx == regbar) { - if (ntb->b2b_off) - bar_addr += ntb->b2b_off; - else - bar_addr = 0; - } - - if (!bar_is_64bit(ntb, idx)) { - intel_ntb_reg_write(4, base_reg, bar_addr); - reg_val = intel_ntb_reg_read(4, base_reg); - (void)reg_val; - - intel_ntb_reg_write(4, lmt_reg, bar_addr); - reg_val = intel_ntb_reg_read(4, lmt_reg); - (void)reg_val; - } else { - intel_ntb_reg_write(8, base_reg, bar_addr); - reg_val = intel_ntb_reg_read(8, base_reg); - (void)reg_val; - - intel_ntb_reg_write(8, lmt_reg, bar_addr); - reg_val = intel_ntb_reg_read(8, lmt_reg); - (void)reg_val; - } -} - -static void -xeon_set_pbar_xlat(struct ntb_softc *ntb, uint64_t base_addr, enum ntb_bar idx) -{ - struct ntb_pci_bar_info *bar; - - bar = &ntb->bar_info[idx]; - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR) && idx >= NTB_B2B_BAR_2) { - intel_ntb_reg_write(4, bar->pbarxlat_off, base_addr); - base_addr = intel_ntb_reg_read(4, bar->pbarxlat_off); - } else { - intel_ntb_reg_write(8, bar->pbarxlat_off, base_addr); - base_addr = intel_ntb_reg_read(8, bar->pbarxlat_off); - } - (void)base_addr; -} - -static int -xeon_setup_b2b_mw(struct ntb_softc *ntb, const struct ntb_b2b_addr *addr, - const struct ntb_b2b_addr *peer_addr) -{ - struct ntb_pci_bar_info *b2b_bar; - vm_size_t bar_size; - uint64_t bar_addr; - enum ntb_bar b2b_bar_num, i; - - if (ntb->b2b_mw_idx == B2B_MW_DISABLED) { - b2b_bar = NULL; - b2b_bar_num = NTB_CONFIG_BAR; - ntb->b2b_off = 0; - } else { - b2b_bar_num = intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx); - KASSERT(b2b_bar_num > 0 && b2b_bar_num < NTB_MAX_BARS, - ("invalid b2b mw bar")); - - b2b_bar = &ntb->bar_info[b2b_bar_num]; - bar_size = b2b_bar->size; - - if (ntb_b2b_mw_share != 0 && - (bar_size >> 1) >= XEON_B2B_MIN_SIZE) - ntb->b2b_off = bar_size >> 1; - else if (bar_size >= XEON_B2B_MIN_SIZE) { - ntb->b2b_off = 0; - } else { - device_printf(ntb->device, - "B2B bar size is too small!\n"); - return (EIO); - } - } - - /* - * Reset the secondary bar sizes to match the primary bar sizes. - * (Except, disable or halve the size of the B2B secondary bar.) - */ - for (i = NTB_B2B_BAR_1; i < NTB_MAX_BARS; i++) - xeon_reset_sbar_size(ntb, i, b2b_bar_num); - - bar_addr = 0; - if (b2b_bar_num == NTB_CONFIG_BAR) - bar_addr = addr->bar0_addr; - else if (b2b_bar_num == NTB_B2B_BAR_1) - bar_addr = addr->bar2_addr64; - else if (b2b_bar_num == NTB_B2B_BAR_2 && !HAS_FEATURE(ntb, NTB_SPLIT_BAR)) - bar_addr = addr->bar4_addr64; - else if (b2b_bar_num == NTB_B2B_BAR_2) - bar_addr = addr->bar4_addr32; - else if (b2b_bar_num == NTB_B2B_BAR_3) - bar_addr = addr->bar5_addr32; - else - KASSERT(false, ("invalid bar")); - - intel_ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, bar_addr); - - /* - * Other SBARs are normally hit by the PBAR xlat, except for the b2b - * register BAR. The B2B BAR is either disabled above or configured - * half-size. It starts at PBAR xlat + offset. - * - * Also set up incoming BAR limits == base (zero length window). - */ - xeon_set_sbar_base_and_limit(ntb, addr->bar2_addr64, NTB_B2B_BAR_1, - b2b_bar_num); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - xeon_set_sbar_base_and_limit(ntb, addr->bar4_addr32, - NTB_B2B_BAR_2, b2b_bar_num); - xeon_set_sbar_base_and_limit(ntb, addr->bar5_addr32, - NTB_B2B_BAR_3, b2b_bar_num); - } else - xeon_set_sbar_base_and_limit(ntb, addr->bar4_addr64, - NTB_B2B_BAR_2, b2b_bar_num); - - /* Zero incoming translation addrs */ - intel_ntb_reg_write(8, XEON_SBAR2XLAT_OFFSET, 0); - intel_ntb_reg_write(8, XEON_SBAR4XLAT_OFFSET, 0); - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - uint32_t xlat_reg, lmt_reg; - enum ntb_bar bar_num; - - /* - * We point the chosen MSIX MW BAR xlat to remote LAPIC for - * workaround - */ - bar_num = intel_ntb_mw_to_bar(ntb, ntb->msix_mw_idx); - bar_get_xlat_params(ntb, bar_num, NULL, &xlat_reg, &lmt_reg); - if (bar_is_64bit(ntb, bar_num)) { - intel_ntb_reg_write(8, xlat_reg, MSI_INTEL_ADDR_BASE); - ntb->msix_xlat = intel_ntb_reg_read(8, xlat_reg); - intel_ntb_reg_write(8, lmt_reg, 0); - } else { - intel_ntb_reg_write(4, xlat_reg, MSI_INTEL_ADDR_BASE); - ntb->msix_xlat = intel_ntb_reg_read(4, xlat_reg); - intel_ntb_reg_write(4, lmt_reg, 0); - } - - ntb->peer_lapic_bar = &ntb->bar_info[bar_num]; - } - (void)intel_ntb_reg_read(8, XEON_SBAR2XLAT_OFFSET); - (void)intel_ntb_reg_read(8, XEON_SBAR4XLAT_OFFSET); - - /* Zero outgoing translation limits (whole bar size windows) */ - intel_ntb_reg_write(8, XEON_PBAR2LMT_OFFSET, 0); - intel_ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0); - - /* Set outgoing translation offsets */ - xeon_set_pbar_xlat(ntb, peer_addr->bar2_addr64, NTB_B2B_BAR_1); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - xeon_set_pbar_xlat(ntb, peer_addr->bar4_addr32, NTB_B2B_BAR_2); - xeon_set_pbar_xlat(ntb, peer_addr->bar5_addr32, NTB_B2B_BAR_3); - } else - xeon_set_pbar_xlat(ntb, peer_addr->bar4_addr64, NTB_B2B_BAR_2); - - /* Set the translation offset for B2B registers */ - bar_addr = 0; - if (b2b_bar_num == NTB_CONFIG_BAR) - bar_addr = peer_addr->bar0_addr; - else if (b2b_bar_num == NTB_B2B_BAR_1) - bar_addr = peer_addr->bar2_addr64; - else if (b2b_bar_num == NTB_B2B_BAR_2 && !HAS_FEATURE(ntb, NTB_SPLIT_BAR)) - bar_addr = peer_addr->bar4_addr64; - else if (b2b_bar_num == NTB_B2B_BAR_2) - bar_addr = peer_addr->bar4_addr32; - else if (b2b_bar_num == NTB_B2B_BAR_3) - bar_addr = peer_addr->bar5_addr32; - else - KASSERT(false, ("invalid bar")); - - /* - * B2B_XLAT_OFFSET is a 64-bit register but can only be written 32 bits - * at a time. - */ - intel_ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL, bar_addr & 0xffffffff); - intel_ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU, bar_addr >> 32); - return (0); -} - -static inline bool -_xeon_link_is_up(struct ntb_softc *ntb) -{ - - if (ntb->conn_type == NTB_CONN_TRANSPARENT) - return (true); - return ((ntb->lnk_sta & NTB_LINK_STATUS_ACTIVE) != 0); -} - -static inline bool -link_is_up(struct ntb_softc *ntb) -{ - - if (ntb->type == NTB_XEON) - return (_xeon_link_is_up(ntb) && (ntb->peer_msix_good || - !HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP))); - - KASSERT(ntb->type == NTB_ATOM, ("ntb type")); - return ((ntb->ntb_ctl & ATOM_CNTL_LINK_DOWN) == 0); -} - -static inline bool -atom_link_is_err(struct ntb_softc *ntb) -{ - uint32_t status; - - KASSERT(ntb->type == NTB_ATOM, ("ntb type")); - - status = intel_ntb_reg_read(4, ATOM_LTSSMSTATEJMP_OFFSET); - if ((status & ATOM_LTSSMSTATEJMP_FORCEDETECT) != 0) - return (true); - - status = intel_ntb_reg_read(4, ATOM_IBSTERRRCRVSTS0_OFFSET); - return ((status & ATOM_IBIST_ERR_OFLOW) != 0); -} - -/* Atom does not have link status interrupt, poll on that platform */ -static void -atom_link_hb(void *arg) -{ - struct ntb_softc *ntb = arg; - sbintime_t timo, poll_ts; - - timo = NTB_HB_TIMEOUT * hz; - poll_ts = ntb->last_ts + timo; - - /* - * Delay polling the link status if an interrupt was received, unless - * the cached link status says the link is down. - */ - if ((sbintime_t)ticks - poll_ts < 0 && link_is_up(ntb)) { - timo = poll_ts - ticks; - goto out; - } - - if (intel_ntb_poll_link(ntb)) - ntb_link_event(ntb->device); - - if (!link_is_up(ntb) && atom_link_is_err(ntb)) { - /* Link is down with error, proceed with recovery */ - callout_reset(&ntb->lr_timer, 0, recover_atom_link, ntb); - return; - } - -out: - callout_reset(&ntb->heartbeat_timer, timo, atom_link_hb, ntb); -} - -static void -atom_perform_link_restart(struct ntb_softc *ntb) -{ - uint32_t status; - - /* Driver resets the NTB ModPhy lanes - magic! */ - intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG6, 0xe0); - intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG4, 0x40); - intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG4, 0x60); - intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG6, 0x60); - - /* Driver waits 100ms to allow the NTB ModPhy to settle */ - pause("ModPhy", hz / 10); - - /* Clear AER Errors, write to clear */ - status = intel_ntb_reg_read(4, ATOM_ERRCORSTS_OFFSET); - status &= PCIM_AER_COR_REPLAY_ROLLOVER; - intel_ntb_reg_write(4, ATOM_ERRCORSTS_OFFSET, status); - - /* Clear unexpected electrical idle event in LTSSM, write to clear */ - status = intel_ntb_reg_read(4, ATOM_LTSSMERRSTS0_OFFSET); - status |= ATOM_LTSSMERRSTS0_UNEXPECTEDEI; - intel_ntb_reg_write(4, ATOM_LTSSMERRSTS0_OFFSET, status); - - /* Clear DeSkew Buffer error, write to clear */ - status = intel_ntb_reg_read(4, ATOM_DESKEWSTS_OFFSET); - status |= ATOM_DESKEWSTS_DBERR; - intel_ntb_reg_write(4, ATOM_DESKEWSTS_OFFSET, status); - - status = intel_ntb_reg_read(4, ATOM_IBSTERRRCRVSTS0_OFFSET); - status &= ATOM_IBIST_ERR_OFLOW; - intel_ntb_reg_write(4, ATOM_IBSTERRRCRVSTS0_OFFSET, status); - - /* Releases the NTB state machine to allow the link to retrain */ - status = intel_ntb_reg_read(4, ATOM_LTSSMSTATEJMP_OFFSET); - status &= ~ATOM_LTSSMSTATEJMP_FORCEDETECT; - intel_ntb_reg_write(4, ATOM_LTSSMSTATEJMP_OFFSET, status); -} - -static int -intel_ntb_link_enable(device_t dev, enum ntb_speed speed __unused, - enum ntb_width width __unused) -{ - struct ntb_softc *ntb = device_get_softc(dev); - uint32_t cntl; - - intel_ntb_printf(2, "%s\n", __func__); - - if (ntb->type == NTB_ATOM) { - pci_write_config(ntb->device, NTB_PPD_OFFSET, - ntb->ppd | ATOM_PPD_INIT_LINK, 4); - return (0); - } - - if (ntb->conn_type == NTB_CONN_TRANSPARENT) { - ntb_link_event(dev); - return (0); - } - - cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); - cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK); - cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP; - cntl |= NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP; - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) - cntl |= NTB_CNTL_P2S_BAR5_SNOOP | NTB_CNTL_S2P_BAR5_SNOOP; - intel_ntb_reg_write(4, ntb->reg->ntb_ctl, cntl); - return (0); -} - -static int -intel_ntb_link_disable(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - uint32_t cntl; - - intel_ntb_printf(2, "%s\n", __func__); - - if (ntb->conn_type == NTB_CONN_TRANSPARENT) { - ntb_link_event(dev); - return (0); - } - - cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); - cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP); - cntl &= ~(NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) - cntl &= ~(NTB_CNTL_P2S_BAR5_SNOOP | NTB_CNTL_S2P_BAR5_SNOOP); - cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK; - intel_ntb_reg_write(4, ntb->reg->ntb_ctl, cntl); - return (0); -} - -static bool -intel_ntb_link_enabled(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - uint32_t cntl; - - if (ntb->type == NTB_ATOM) { - cntl = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4); - return ((cntl & ATOM_PPD_INIT_LINK) != 0); - } - - if (ntb->conn_type == NTB_CONN_TRANSPARENT) - return (true); - - cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); - return ((cntl & NTB_CNTL_LINK_DISABLE) == 0); -} - -static void -recover_atom_link(void *arg) -{ - struct ntb_softc *ntb = arg; - unsigned speed, width, oldspeed, oldwidth; - uint32_t status32; - - atom_perform_link_restart(ntb); - - /* - * There is a potential race between the 2 NTB devices recovering at - * the same time. If the times are the same, the link will not recover - * and the driver will be stuck in this loop forever. Add a random - * interval to the recovery time to prevent this race. - */ - status32 = arc4random() % ATOM_LINK_RECOVERY_TIME; - pause("Link", (ATOM_LINK_RECOVERY_TIME + status32) * hz / 1000); - - if (atom_link_is_err(ntb)) - goto retry; - - status32 = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); - if ((status32 & ATOM_CNTL_LINK_DOWN) != 0) - goto out; - - status32 = intel_ntb_reg_read(4, ntb->reg->lnk_sta); - width = NTB_LNK_STA_WIDTH(status32); - speed = status32 & NTB_LINK_SPEED_MASK; - - oldwidth = NTB_LNK_STA_WIDTH(ntb->lnk_sta); - oldspeed = ntb->lnk_sta & NTB_LINK_SPEED_MASK; - if (oldwidth != width || oldspeed != speed) - goto retry; - -out: - callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, atom_link_hb, - ntb); - return; - -retry: - callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_atom_link, - ntb); -} - -/* - * Polls the HW link status register(s); returns true if something has changed. - */ -static bool -intel_ntb_poll_link(struct ntb_softc *ntb) -{ - uint32_t ntb_cntl; - uint16_t reg_val; - - if (ntb->type == NTB_ATOM) { - ntb_cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); - if (ntb_cntl == ntb->ntb_ctl) - return (false); - - ntb->ntb_ctl = ntb_cntl; - ntb->lnk_sta = intel_ntb_reg_read(4, ntb->reg->lnk_sta); - } else { - db_iowrite_raw(ntb, ntb->self_reg->db_bell, ntb->db_link_mask); - - reg_val = pci_read_config(ntb->device, ntb->reg->lnk_sta, 2); - if (reg_val == ntb->lnk_sta) - return (false); - - ntb->lnk_sta = reg_val; - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - if (_xeon_link_is_up(ntb)) { - if (!ntb->peer_msix_good) { - callout_reset(&ntb->peer_msix_work, 0, - intel_ntb_exchange_msix, ntb); - return (false); - } - } else { - ntb->peer_msix_good = false; - ntb->peer_msix_done = false; - } - } - } - return (true); -} - -static inline enum ntb_speed -intel_ntb_link_sta_speed(struct ntb_softc *ntb) -{ - - if (!link_is_up(ntb)) - return (NTB_SPEED_NONE); - return (ntb->lnk_sta & NTB_LINK_SPEED_MASK); -} - -static inline enum ntb_width -intel_ntb_link_sta_width(struct ntb_softc *ntb) -{ - - if (!link_is_up(ntb)) - return (NTB_WIDTH_NONE); - return (NTB_LNK_STA_WIDTH(ntb->lnk_sta)); -} - -SYSCTL_NODE(_hw_ntb, OID_AUTO, debug_info, CTLFLAG_RW, 0, - "Driver state, statistics, and HW registers"); - -#define NTB_REGSZ_MASK (3ul << 30) -#define NTB_REG_64 (1ul << 30) -#define NTB_REG_32 (2ul << 30) -#define NTB_REG_16 (3ul << 30) -#define NTB_REG_8 (0ul << 30) - -#define NTB_DB_READ (1ul << 29) -#define NTB_PCI_REG (1ul << 28) -#define NTB_REGFLAGS_MASK (NTB_REGSZ_MASK | NTB_DB_READ | NTB_PCI_REG) - -static void -intel_ntb_sysctl_init(struct ntb_softc *ntb) -{ - struct sysctl_oid_list *globals, *tree_par, *regpar, *statpar, *errpar; - struct sysctl_ctx_list *ctx; - struct sysctl_oid *tree, *tmptree; - - ctx = device_get_sysctl_ctx(ntb->device); - globals = SYSCTL_CHILDREN(device_get_sysctl_tree(ntb->device)); - - SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "link_status", - CTLFLAG_RD | CTLTYPE_STRING, ntb, 0, - sysctl_handle_link_status_human, "A", - "Link status (human readable)"); - SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "active", - CTLFLAG_RD | CTLTYPE_UINT, ntb, 0, sysctl_handle_link_status, - "IU", "Link status (1=active, 0=inactive)"); - SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "admin_up", - CTLFLAG_RW | CTLTYPE_UINT, ntb, 0, sysctl_handle_link_admin, - "IU", "Set/get interface status (1=UP, 0=DOWN)"); - - tree = SYSCTL_ADD_NODE(ctx, globals, OID_AUTO, "debug_info", - CTLFLAG_RD, NULL, "Driver state, statistics, and HW registers"); - tree_par = SYSCTL_CHILDREN(tree); - - SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "conn_type", CTLFLAG_RD, - &ntb->conn_type, 0, "0 - Transparent; 1 - B2B; 2 - Root Port"); - SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "dev_type", CTLFLAG_RD, - &ntb->dev_type, 0, "0 - USD; 1 - DSD"); - SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "ppd", CTLFLAG_RD, - &ntb->ppd, 0, "Raw PPD register (cached)"); - - if (ntb->b2b_mw_idx != B2B_MW_DISABLED) { - SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "b2b_idx", CTLFLAG_RD, - &ntb->b2b_mw_idx, 0, - "Index of the MW used for B2B remote register access"); - SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "b2b_off", - CTLFLAG_RD, &ntb->b2b_off, - "If non-zero, offset of B2B register region in shared MW"); - } - - SYSCTL_ADD_PROC(ctx, tree_par, OID_AUTO, "features", - CTLFLAG_RD | CTLTYPE_STRING, ntb, 0, sysctl_handle_features, "A", - "Features/errata of this NTB device"); - - SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "ntb_ctl", CTLFLAG_RD, - __DEVOLATILE(uint32_t *, &ntb->ntb_ctl), 0, - "NTB CTL register (cached)"); - SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "lnk_sta", CTLFLAG_RD, - __DEVOLATILE(uint32_t *, &ntb->lnk_sta), 0, - "LNK STA register (cached)"); - - SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "mw_count", CTLFLAG_RD, - &ntb->mw_count, 0, "MW count"); - SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "spad_count", CTLFLAG_RD, - &ntb->spad_count, 0, "Scratchpad count"); - SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "db_count", CTLFLAG_RD, - &ntb->db_count, 0, "Doorbell count"); - SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "db_vec_count", CTLFLAG_RD, - &ntb->db_vec_count, 0, "Doorbell vector count"); - SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "db_vec_shift", CTLFLAG_RD, - &ntb->db_vec_shift, 0, "Doorbell vector shift"); - - SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "db_valid_mask", CTLFLAG_RD, - &ntb->db_valid_mask, "Doorbell valid mask"); - SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "db_link_mask", CTLFLAG_RD, - &ntb->db_link_mask, "Doorbell link mask"); - SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "db_mask", CTLFLAG_RD, - &ntb->db_mask, "Doorbell mask (cached)"); - - tmptree = SYSCTL_ADD_NODE(ctx, tree_par, OID_AUTO, "registers", - CTLFLAG_RD, NULL, "Raw HW registers (big-endian)"); - regpar = SYSCTL_CHILDREN(tmptree); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "ntbcntl", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, NTB_REG_32 | - ntb->reg->ntb_ctl, sysctl_handle_register, "IU", - "NTB Control register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "lnkcap", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, NTB_REG_32 | - 0x19c, sysctl_handle_register, "IU", - "NTB Link Capabilities"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "lnkcon", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, NTB_REG_32 | - 0x1a0, sysctl_handle_register, "IU", - "NTB Link Control register"); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "db_mask", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | NTB_DB_READ | ntb->self_reg->db_mask, - sysctl_handle_register, "QU", "Doorbell mask register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "db_bell", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | NTB_DB_READ | ntb->self_reg->db_bell, - sysctl_handle_register, "QU", "Doorbell register"); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat23", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar2_xlat, - sysctl_handle_register, "QU", "Incoming XLAT23 register"); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat4", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->xlat_reg->bar4_xlat, - sysctl_handle_register, "IU", "Incoming XLAT4 register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat5", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->xlat_reg->bar5_xlat, - sysctl_handle_register, "IU", "Incoming XLAT5 register"); - } else { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat45", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar4_xlat, - sysctl_handle_register, "QU", "Incoming XLAT45 register"); - } - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt23", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar2_limit, - sysctl_handle_register, "QU", "Incoming LMT23 register"); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt4", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->xlat_reg->bar4_limit, - sysctl_handle_register, "IU", "Incoming LMT4 register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt5", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->xlat_reg->bar5_limit, - sysctl_handle_register, "IU", "Incoming LMT5 register"); - } else { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt45", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar4_limit, - sysctl_handle_register, "QU", "Incoming LMT45 register"); - } - - if (ntb->type == NTB_ATOM) - return; - - tmptree = SYSCTL_ADD_NODE(ctx, regpar, OID_AUTO, "xeon_stats", - CTLFLAG_RD, NULL, "Xeon HW statistics"); - statpar = SYSCTL_CHILDREN(tmptree); - SYSCTL_ADD_PROC(ctx, statpar, OID_AUTO, "upstream_mem_miss", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_16 | XEON_USMEMMISS_OFFSET, - sysctl_handle_register, "SU", "Upstream Memory Miss"); - - tmptree = SYSCTL_ADD_NODE(ctx, regpar, OID_AUTO, "xeon_hw_err", - CTLFLAG_RD, NULL, "Xeon HW errors"); - errpar = SYSCTL_CHILDREN(tmptree); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "ppd", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | NTB_PPD_OFFSET, - sysctl_handle_register, "CU", "PPD"); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "pbar23_sz", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | XEON_PBAR23SZ_OFFSET, - sysctl_handle_register, "CU", "PBAR23 SZ (log2)"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "pbar4_sz", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | XEON_PBAR4SZ_OFFSET, - sysctl_handle_register, "CU", "PBAR4 SZ (log2)"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "pbar5_sz", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | XEON_PBAR5SZ_OFFSET, - sysctl_handle_register, "CU", "PBAR5 SZ (log2)"); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar23_sz", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | XEON_SBAR23SZ_OFFSET, - sysctl_handle_register, "CU", "SBAR23 SZ (log2)"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar4_sz", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | XEON_SBAR4SZ_OFFSET, - sysctl_handle_register, "CU", "SBAR4 SZ (log2)"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar5_sz", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_8 | NTB_PCI_REG | XEON_SBAR5SZ_OFFSET, - sysctl_handle_register, "CU", "SBAR5 SZ (log2)"); - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "devsts", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_16 | NTB_PCI_REG | XEON_DEVSTS_OFFSET, - sysctl_handle_register, "SU", "DEVSTS"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "lnksts", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_16 | NTB_PCI_REG | XEON_LINK_STATUS_OFFSET, - sysctl_handle_register, "SU", "LNKSTS"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "slnksts", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_16 | NTB_PCI_REG | XEON_SLINK_STATUS_OFFSET, - sysctl_handle_register, "SU", "SLNKSTS"); - - SYSCTL_ADD_PROC(ctx, errpar, OID_AUTO, "uncerrsts", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | NTB_PCI_REG | XEON_UNCERRSTS_OFFSET, - sysctl_handle_register, "IU", "UNCERRSTS"); - SYSCTL_ADD_PROC(ctx, errpar, OID_AUTO, "corerrsts", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | NTB_PCI_REG | XEON_CORERRSTS_OFFSET, - sysctl_handle_register, "IU", "CORERRSTS"); - - if (ntb->conn_type != NTB_CONN_B2B) - return; - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat23", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->bar_info[NTB_B2B_BAR_1].pbarxlat_off, - sysctl_handle_register, "QU", "Outgoing XLAT23 register"); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat4", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->bar_info[NTB_B2B_BAR_2].pbarxlat_off, - sysctl_handle_register, "IU", "Outgoing XLAT4 register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat5", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->bar_info[NTB_B2B_BAR_3].pbarxlat_off, - sysctl_handle_register, "IU", "Outgoing XLAT5 register"); - } else { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat45", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->bar_info[NTB_B2B_BAR_2].pbarxlat_off, - sysctl_handle_register, "QU", "Outgoing XLAT45 register"); - } - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt23", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | XEON_PBAR2LMT_OFFSET, - sysctl_handle_register, "QU", "Outgoing LMT23 register"); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt4", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | XEON_PBAR4LMT_OFFSET, - sysctl_handle_register, "IU", "Outgoing LMT4 register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt5", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | XEON_PBAR5LMT_OFFSET, - sysctl_handle_register, "IU", "Outgoing LMT5 register"); - } else { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt45", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | XEON_PBAR4LMT_OFFSET, - sysctl_handle_register, "QU", "Outgoing LMT45 register"); - } - - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar01_base", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar0_base, - sysctl_handle_register, "QU", "Secondary BAR01 base register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar23_base", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar2_base, - sysctl_handle_register, "QU", "Secondary BAR23 base register"); - if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar4_base", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->xlat_reg->bar4_base, - sysctl_handle_register, "IU", - "Secondary BAR4 base register"); - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar5_base", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_32 | ntb->xlat_reg->bar5_base, - sysctl_handle_register, "IU", - "Secondary BAR5 base register"); - } else { - SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar45_base", - CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, - NTB_REG_64 | ntb->xlat_reg->bar4_base, - sysctl_handle_register, "QU", - "Secondary BAR45 base register"); - } -} - -static int -sysctl_handle_features(SYSCTL_HANDLER_ARGS) -{ - struct ntb_softc *ntb = arg1; - struct sbuf sb; - int error; - - sbuf_new_for_sysctl(&sb, NULL, 256, req); - - sbuf_printf(&sb, "%b", ntb->features, NTB_FEATURES_STR); - error = sbuf_finish(&sb); - sbuf_delete(&sb); - - if (error || !req->newptr) - return (error); - return (EINVAL); -} - -static int -sysctl_handle_link_admin(SYSCTL_HANDLER_ARGS) -{ - struct ntb_softc *ntb = arg1; - unsigned old, new; - int error; - - old = intel_ntb_link_enabled(ntb->device); - - error = SYSCTL_OUT(req, &old, sizeof(old)); - if (error != 0 || req->newptr == NULL) - return (error); - - error = SYSCTL_IN(req, &new, sizeof(new)); - if (error != 0) - return (error); - - intel_ntb_printf(0, "Admin set interface state to '%sabled'\n", - (new != 0)? "en" : "dis"); - - if (new != 0) - error = intel_ntb_link_enable(ntb->device, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); - else - error = intel_ntb_link_disable(ntb->device); - return (error); -} - -static int -sysctl_handle_link_status_human(SYSCTL_HANDLER_ARGS) -{ - struct ntb_softc *ntb = arg1; - struct sbuf sb; - enum ntb_speed speed; - enum ntb_width width; - int error; - - sbuf_new_for_sysctl(&sb, NULL, 32, req); - - if (intel_ntb_link_is_up(ntb->device, &speed, &width)) - sbuf_printf(&sb, "up / PCIe Gen %u / Width x%u", - (unsigned)speed, (unsigned)width); - else - sbuf_printf(&sb, "down"); - - error = sbuf_finish(&sb); - sbuf_delete(&sb); - - if (error || !req->newptr) - return (error); - return (EINVAL); -} - -static int -sysctl_handle_link_status(SYSCTL_HANDLER_ARGS) -{ - struct ntb_softc *ntb = arg1; - unsigned res; - int error; - - res = intel_ntb_link_is_up(ntb->device, NULL, NULL); - - error = SYSCTL_OUT(req, &res, sizeof(res)); - if (error || !req->newptr) - return (error); - return (EINVAL); -} - -static int -sysctl_handle_register(SYSCTL_HANDLER_ARGS) -{ - struct ntb_softc *ntb; - const void *outp; - uintptr_t sz; - uint64_t umv; - char be[sizeof(umv)]; - size_t outsz; - uint32_t reg; - bool db, pci; - int error; - - ntb = arg1; - reg = arg2 & ~NTB_REGFLAGS_MASK; - sz = arg2 & NTB_REGSZ_MASK; - db = (arg2 & NTB_DB_READ) != 0; - pci = (arg2 & NTB_PCI_REG) != 0; - - KASSERT(!(db && pci), ("bogus")); - - if (db) { - KASSERT(sz == NTB_REG_64, ("bogus")); - umv = db_ioread(ntb, reg); - outsz = sizeof(uint64_t); - } else { - switch (sz) { - case NTB_REG_64: - if (pci) - umv = pci_read_config(ntb->device, reg, 8); - else - umv = intel_ntb_reg_read(8, reg); - outsz = sizeof(uint64_t); - break; - case NTB_REG_32: - if (pci) - umv = pci_read_config(ntb->device, reg, 4); - else - umv = intel_ntb_reg_read(4, reg); - outsz = sizeof(uint32_t); - break; - case NTB_REG_16: - if (pci) - umv = pci_read_config(ntb->device, reg, 2); - else - umv = intel_ntb_reg_read(2, reg); - outsz = sizeof(uint16_t); - break; - case NTB_REG_8: - if (pci) - umv = pci_read_config(ntb->device, reg, 1); - else - umv = intel_ntb_reg_read(1, reg); - outsz = sizeof(uint8_t); - break; - default: - panic("bogus"); - break; - } - } - - /* Encode bigendian so that sysctl -x is legible. */ - be64enc(be, umv); - outp = ((char *)be) + sizeof(umv) - outsz; - - error = SYSCTL_OUT(req, outp, outsz); - if (error || !req->newptr) - return (error); - return (EINVAL); -} - -static unsigned -intel_ntb_user_mw_to_idx(struct ntb_softc *ntb, unsigned uidx) -{ - - if ((ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && - uidx >= ntb->b2b_mw_idx) || - (ntb->msix_mw_idx != B2B_MW_DISABLED && uidx >= ntb->msix_mw_idx)) - uidx++; - if ((ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && - uidx >= ntb->b2b_mw_idx) && - (ntb->msix_mw_idx != B2B_MW_DISABLED && uidx >= ntb->msix_mw_idx)) - uidx++; - return (uidx); -} - -#ifndef EARLY_AP_STARTUP -static int msix_ready; - -static void -intel_ntb_msix_ready(void *arg __unused) -{ - - msix_ready = 1; -} -SYSINIT(intel_ntb_msix_ready, SI_SUB_SMP, SI_ORDER_ANY, - intel_ntb_msix_ready, NULL); -#endif - -static void -intel_ntb_exchange_msix(void *ctx) -{ - struct ntb_softc *ntb; - uint32_t val; - unsigned i; - - ntb = ctx; - - if (ntb->peer_msix_good) - goto msix_good; - if (ntb->peer_msix_done) - goto msix_done; - -#ifndef EARLY_AP_STARTUP - /* Block MSIX negotiation until SMP started and IRQ reshuffled. */ - if (!msix_ready) - goto reschedule; -#endif - - intel_ntb_get_msix_info(ntb); - for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { - intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_DATA0 + i, - ntb->msix_data[i].nmd_data); - intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_OFS0 + i, - ntb->msix_data[i].nmd_ofs - ntb->msix_xlat); - } - intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_GUARD, NTB_MSIX_VER_GUARD); - - intel_ntb_spad_read(ntb->device, NTB_MSIX_GUARD, &val); - if (val != NTB_MSIX_VER_GUARD) - goto reschedule; - - for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { - intel_ntb_spad_read(ntb->device, NTB_MSIX_DATA0 + i, &val); - intel_ntb_printf(2, "remote MSIX data(%u): 0x%x\n", i, val); - ntb->peer_msix_data[i].nmd_data = val; - intel_ntb_spad_read(ntb->device, NTB_MSIX_OFS0 + i, &val); - intel_ntb_printf(2, "remote MSIX addr(%u): 0x%x\n", i, val); - ntb->peer_msix_data[i].nmd_ofs = val; - } - - ntb->peer_msix_done = true; - -msix_done: - intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_DONE, NTB_MSIX_RECEIVED); - intel_ntb_spad_read(ntb->device, NTB_MSIX_DONE, &val); - if (val != NTB_MSIX_RECEIVED) - goto reschedule; - - intel_ntb_spad_clear(ntb->device); - ntb->peer_msix_good = true; - /* Give peer time to see our NTB_MSIX_RECEIVED. */ - goto reschedule; - -msix_good: - intel_ntb_poll_link(ntb); - ntb_link_event(ntb->device); - return; - -reschedule: - ntb->lnk_sta = pci_read_config(ntb->device, ntb->reg->lnk_sta, 2); - if (_xeon_link_is_up(ntb)) { - callout_reset(&ntb->peer_msix_work, - hz * (ntb->peer_msix_good ? 2 : 1) / 100, - intel_ntb_exchange_msix, ntb); - } else - intel_ntb_spad_clear(ntb->device); -} - -/* - * Public API to the rest of the OS - */ - -static uint8_t -intel_ntb_spad_count(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - return (ntb->spad_count); -} - -static uint8_t -intel_ntb_mw_count(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - uint8_t res; - - res = ntb->mw_count; - if (ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0) - res--; - if (ntb->msix_mw_idx != B2B_MW_DISABLED) - res--; - return (res); -} - -static int -intel_ntb_spad_write(device_t dev, unsigned int idx, uint32_t val) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (idx >= ntb->spad_count) - return (EINVAL); - - intel_ntb_reg_write(4, ntb->self_reg->spad + idx * 4, val); - - return (0); -} - -/* - * Zeros the local scratchpad. - */ -static void -intel_ntb_spad_clear(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - unsigned i; - - for (i = 0; i < ntb->spad_count; i++) - intel_ntb_spad_write(dev, i, 0); -} - -static int -intel_ntb_spad_read(device_t dev, unsigned int idx, uint32_t *val) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (idx >= ntb->spad_count) - return (EINVAL); - - *val = intel_ntb_reg_read(4, ntb->self_reg->spad + idx * 4); - - return (0); -} - -static int -intel_ntb_peer_spad_write(device_t dev, unsigned int idx, uint32_t val) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (idx >= ntb->spad_count) - return (EINVAL); - - if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) - intel_ntb_mw_write(4, XEON_SPAD_OFFSET + idx * 4, val); - else - intel_ntb_reg_write(4, ntb->peer_reg->spad + idx * 4, val); - - return (0); -} - -static int -intel_ntb_peer_spad_read(device_t dev, unsigned int idx, uint32_t *val) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (idx >= ntb->spad_count) - return (EINVAL); - - if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) - *val = intel_ntb_mw_read(4, XEON_SPAD_OFFSET + idx * 4); - else - *val = intel_ntb_reg_read(4, ntb->peer_reg->spad + idx * 4); - - return (0); -} - -static int -intel_ntb_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base, - caddr_t *vbase, size_t *size, size_t *align, size_t *align_size, - bus_addr_t *plimit) -{ - struct ntb_softc *ntb = device_get_softc(dev); - struct ntb_pci_bar_info *bar; - bus_addr_t limit; - size_t bar_b2b_off; - enum ntb_bar bar_num; - - if (mw_idx >= intel_ntb_mw_count(dev)) - return (EINVAL); - mw_idx = intel_ntb_user_mw_to_idx(ntb, mw_idx); - - bar_num = intel_ntb_mw_to_bar(ntb, mw_idx); - bar = &ntb->bar_info[bar_num]; - bar_b2b_off = 0; - if (mw_idx == ntb->b2b_mw_idx) { - KASSERT(ntb->b2b_off != 0, - ("user shouldn't get non-shared b2b mw")); - bar_b2b_off = ntb->b2b_off; - } - - if (bar_is_64bit(ntb, bar_num)) - limit = BUS_SPACE_MAXADDR; - else - limit = BUS_SPACE_MAXADDR_32BIT; - - if (base != NULL) - *base = bar->pbase + bar_b2b_off; - if (vbase != NULL) - *vbase = bar->vbase + bar_b2b_off; - if (size != NULL) - *size = bar->size - bar_b2b_off; - if (align != NULL) - *align = bar->size; - if (align_size != NULL) - *align_size = 1; - if (plimit != NULL) - *plimit = limit; - return (0); -} - -static int -intel_ntb_mw_set_trans(device_t dev, unsigned idx, bus_addr_t addr, size_t size) -{ - struct ntb_softc *ntb = device_get_softc(dev); - struct ntb_pci_bar_info *bar; - uint64_t base, limit, reg_val; - size_t bar_size, mw_size; - uint32_t base_reg, xlat_reg, limit_reg; - enum ntb_bar bar_num; - - if (idx >= intel_ntb_mw_count(dev)) - return (EINVAL); - idx = intel_ntb_user_mw_to_idx(ntb, idx); - - bar_num = intel_ntb_mw_to_bar(ntb, idx); - bar = &ntb->bar_info[bar_num]; - - bar_size = bar->size; - if (idx == ntb->b2b_mw_idx) - mw_size = bar_size - ntb->b2b_off; - else - mw_size = bar_size; - - /* Hardware requires that addr is aligned to bar size */ - if ((addr & (bar_size - 1)) != 0) - return (EINVAL); - - if (size > mw_size) - return (EINVAL); - - bar_get_xlat_params(ntb, bar_num, &base_reg, &xlat_reg, &limit_reg); - - limit = 0; - if (bar_is_64bit(ntb, bar_num)) { - base = intel_ntb_reg_read(8, base_reg) & BAR_HIGH_MASK; - - if (limit_reg != 0 && size != mw_size) - limit = base + size; - - /* Set and verify translation address */ - intel_ntb_reg_write(8, xlat_reg, addr); - reg_val = intel_ntb_reg_read(8, xlat_reg) & BAR_HIGH_MASK; - if (reg_val != addr) { - intel_ntb_reg_write(8, xlat_reg, 0); - return (EIO); - } - - /* Set and verify the limit */ - intel_ntb_reg_write(8, limit_reg, limit); - reg_val = intel_ntb_reg_read(8, limit_reg) & BAR_HIGH_MASK; - if (reg_val != limit) { - intel_ntb_reg_write(8, limit_reg, base); - intel_ntb_reg_write(8, xlat_reg, 0); - return (EIO); - } - } else { - /* Configure 32-bit (split) BAR MW */ - - if ((addr & UINT32_MAX) != addr) - return (ERANGE); - if (((addr + size) & UINT32_MAX) != (addr + size)) - return (ERANGE); - - base = intel_ntb_reg_read(4, base_reg) & BAR_HIGH_MASK; - - if (limit_reg != 0 && size != mw_size) - limit = base + size; - - /* Set and verify translation address */ - intel_ntb_reg_write(4, xlat_reg, addr); - reg_val = intel_ntb_reg_read(4, xlat_reg) & BAR_HIGH_MASK; - if (reg_val != addr) { - intel_ntb_reg_write(4, xlat_reg, 0); - return (EIO); - } - - /* Set and verify the limit */ - intel_ntb_reg_write(4, limit_reg, limit); - reg_val = intel_ntb_reg_read(4, limit_reg) & BAR_HIGH_MASK; - if (reg_val != limit) { - intel_ntb_reg_write(4, limit_reg, base); - intel_ntb_reg_write(4, xlat_reg, 0); - return (EIO); - } - } - return (0); -} - -static int -intel_ntb_mw_clear_trans(device_t dev, unsigned mw_idx) -{ - - return (intel_ntb_mw_set_trans(dev, mw_idx, 0, 0)); -} - -static int -intel_ntb_mw_get_wc(device_t dev, unsigned idx, vm_memattr_t *mode) -{ - struct ntb_softc *ntb = device_get_softc(dev); - struct ntb_pci_bar_info *bar; - - if (idx >= intel_ntb_mw_count(dev)) - return (EINVAL); - idx = intel_ntb_user_mw_to_idx(ntb, idx); - - bar = &ntb->bar_info[intel_ntb_mw_to_bar(ntb, idx)]; - *mode = bar->map_mode; - return (0); -} - -static int -intel_ntb_mw_set_wc(device_t dev, unsigned idx, vm_memattr_t mode) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (idx >= intel_ntb_mw_count(dev)) - return (EINVAL); - - idx = intel_ntb_user_mw_to_idx(ntb, idx); - return (intel_ntb_mw_set_wc_internal(ntb, idx, mode)); -} - -static int -intel_ntb_mw_set_wc_internal(struct ntb_softc *ntb, unsigned idx, vm_memattr_t mode) -{ - struct ntb_pci_bar_info *bar; - int rc; - - bar = &ntb->bar_info[intel_ntb_mw_to_bar(ntb, idx)]; - if (bar->map_mode == mode) - return (0); - - rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mode); - if (rc == 0) - bar->map_mode = mode; - - return (rc); -} - -static void -intel_ntb_peer_db_set(device_t dev, uint64_t bit) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { - struct ntb_pci_bar_info *lapic; - unsigned i; - - lapic = ntb->peer_lapic_bar; - - for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { - if ((bit & intel_ntb_db_vector_mask(dev, i)) != 0) - bus_space_write_4(lapic->pci_bus_tag, - lapic->pci_bus_handle, - ntb->peer_msix_data[i].nmd_ofs, - ntb->peer_msix_data[i].nmd_data); - } - return; - } - - if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) { - intel_ntb_mw_write(2, XEON_PDOORBELL_OFFSET, bit); - return; - } - - db_iowrite(ntb, ntb->peer_reg->db_bell, bit); -} - -static int -intel_ntb_peer_db_addr(device_t dev, bus_addr_t *db_addr, vm_size_t *db_size) -{ - struct ntb_softc *ntb = device_get_softc(dev); - struct ntb_pci_bar_info *bar; - uint64_t regoff; - - KASSERT((db_addr != NULL && db_size != NULL), ("must be non-NULL")); - - if (!HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) { - bar = &ntb->bar_info[NTB_CONFIG_BAR]; - regoff = ntb->peer_reg->db_bell; - } else { - KASSERT(ntb->b2b_mw_idx != B2B_MW_DISABLED, - ("invalid b2b idx")); - - bar = &ntb->bar_info[intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx)]; - regoff = XEON_PDOORBELL_OFFSET; - } - KASSERT(bar->pci_bus_tag != X86_BUS_SPACE_IO, ("uh oh")); - - /* HACK: Specific to current x86 bus implementation. */ - *db_addr = ((uint64_t)bar->pci_bus_handle + regoff); - *db_size = ntb->reg->db_size; - return (0); -} - -static uint64_t -intel_ntb_db_valid_mask(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - return (ntb->db_valid_mask); -} - -static int -intel_ntb_db_vector_count(device_t dev) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - return (ntb->db_vec_count); -} - -static uint64_t -intel_ntb_db_vector_mask(device_t dev, uint32_t vector) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (vector > ntb->db_vec_count) - return (0); - return (ntb->db_valid_mask & intel_ntb_vec_mask(ntb, vector)); -} - -static bool -intel_ntb_link_is_up(device_t dev, enum ntb_speed *speed, enum ntb_width *width) -{ - struct ntb_softc *ntb = device_get_softc(dev); - - if (speed != NULL) - *speed = intel_ntb_link_sta_speed(ntb); - if (width != NULL) - *width = intel_ntb_link_sta_width(ntb); - return (link_is_up(ntb)); -} - -static void -save_bar_parameters(struct ntb_pci_bar_info *bar) -{ - - bar->pci_bus_tag = rman_get_bustag(bar->pci_resource); - bar->pci_bus_handle = rman_get_bushandle(bar->pci_resource); - bar->pbase = rman_get_start(bar->pci_resource); - bar->size = rman_get_size(bar->pci_resource); - bar->vbase = rman_get_virtual(bar->pci_resource); -} - -static device_method_t ntb_intel_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, intel_ntb_probe), - DEVMETHOD(device_attach, intel_ntb_attach), - DEVMETHOD(device_detach, intel_ntb_detach), - /* NTB interface */ - DEVMETHOD(ntb_link_is_up, intel_ntb_link_is_up), - DEVMETHOD(ntb_link_enable, intel_ntb_link_enable), - DEVMETHOD(ntb_link_disable, intel_ntb_link_disable), - DEVMETHOD(ntb_link_enabled, intel_ntb_link_enabled), - DEVMETHOD(ntb_mw_count, intel_ntb_mw_count), - DEVMETHOD(ntb_mw_get_range, intel_ntb_mw_get_range), - DEVMETHOD(ntb_mw_set_trans, intel_ntb_mw_set_trans), - DEVMETHOD(ntb_mw_clear_trans, intel_ntb_mw_clear_trans), - DEVMETHOD(ntb_mw_get_wc, intel_ntb_mw_get_wc), - DEVMETHOD(ntb_mw_set_wc, intel_ntb_mw_set_wc), - DEVMETHOD(ntb_spad_count, intel_ntb_spad_count), - DEVMETHOD(ntb_spad_clear, intel_ntb_spad_clear), - DEVMETHOD(ntb_spad_write, intel_ntb_spad_write), - DEVMETHOD(ntb_spad_read, intel_ntb_spad_read), - DEVMETHOD(ntb_peer_spad_write, intel_ntb_peer_spad_write), - DEVMETHOD(ntb_peer_spad_read, intel_ntb_peer_spad_read), - DEVMETHOD(ntb_db_valid_mask, intel_ntb_db_valid_mask), - DEVMETHOD(ntb_db_vector_count, intel_ntb_db_vector_count), - DEVMETHOD(ntb_db_vector_mask, intel_ntb_db_vector_mask), - DEVMETHOD(ntb_db_clear, intel_ntb_db_clear), - DEVMETHOD(ntb_db_clear_mask, intel_ntb_db_clear_mask), - DEVMETHOD(ntb_db_read, intel_ntb_db_read), - DEVMETHOD(ntb_db_set_mask, intel_ntb_db_set_mask), - DEVMETHOD(ntb_peer_db_addr, intel_ntb_peer_db_addr), - DEVMETHOD(ntb_peer_db_set, intel_ntb_peer_db_set), - DEVMETHOD_END -}; - -static DEFINE_CLASS_0(ntb_hw, ntb_intel_driver, ntb_intel_methods, - sizeof(struct ntb_softc)); -DRIVER_MODULE(ntb_intel, pci, ntb_intel_driver, ntb_hw_devclass, NULL, NULL); -MODULE_DEPEND(ntb_intel, ntb, 1, 1, 1); -MODULE_VERSION(ntb_intel, 1); Property changes on: stable/11/sys/dev/ntb/ntb_hw/ntb_hw.c ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.c =================================================================== --- stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.c (nonexistent) +++ stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.c (revision 323453) @@ -0,0 +1,3121 @@ +/*- + * Copyright (c) 2016 Alexander Motin + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2015 EMC Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * The Non-Transparent Bridge (NTB) is a device that allows you to connect + * two or more systems using a PCI-e links, providing remote memory access. + * + * This module contains a driver for NTB hardware in Intel Xeon/Atom CPUs. + * + * NOTE: Much of the code in this module is shared with Linux. Any patches may + * be picked up and redistributed in Linux with a dual GPL/BSD license. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ntb_hw_intel.h" +#include "../ntb.h" + +#define MAX_MSIX_INTERRUPTS MAX(XEON_DB_COUNT, ATOM_DB_COUNT) + +#define NTB_HB_TIMEOUT 1 /* second */ +#define ATOM_LINK_RECOVERY_TIME 500 /* ms */ +#define BAR_HIGH_MASK (~((1ull << 12) - 1)) + +#define NTB_MSIX_VER_GUARD 0xaabbccdd +#define NTB_MSIX_RECEIVED 0xe0f0e0f0 + +/* + * PCI constants could be somewhere more generic, but aren't defined/used in + * pci.c. + */ +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 + +enum ntb_device_type { + NTB_XEON, + NTB_ATOM +}; + +/* ntb_conn_type are hardware numbers, cannot change. */ +enum ntb_conn_type { + NTB_CONN_TRANSPARENT = 0, + NTB_CONN_B2B = 1, + NTB_CONN_RP = 2, +}; + +enum ntb_b2b_direction { + NTB_DEV_USD = 0, + NTB_DEV_DSD = 1, +}; + +enum ntb_bar { + NTB_CONFIG_BAR = 0, + NTB_B2B_BAR_1, + NTB_B2B_BAR_2, + NTB_B2B_BAR_3, + NTB_MAX_BARS +}; + +enum { + NTB_MSIX_GUARD = 0, + NTB_MSIX_DATA0, + NTB_MSIX_DATA1, + NTB_MSIX_DATA2, + NTB_MSIX_OFS0, + NTB_MSIX_OFS1, + NTB_MSIX_OFS2, + NTB_MSIX_DONE, + NTB_MAX_MSIX_SPAD +}; + +/* Device features and workarounds */ +#define HAS_FEATURE(ntb, feature) \ + (((ntb)->features & (feature)) != 0) + +struct ntb_hw_info { + uint32_t device_id; + const char *desc; + enum ntb_device_type type; + uint32_t features; +}; + +struct ntb_pci_bar_info { + bus_space_tag_t pci_bus_tag; + bus_space_handle_t pci_bus_handle; + int pci_resource_id; + struct resource *pci_resource; + vm_paddr_t pbase; + caddr_t vbase; + vm_size_t size; + vm_memattr_t map_mode; + + /* Configuration register offsets */ + uint32_t psz_off; + uint32_t ssz_off; + uint32_t pbarxlat_off; +}; + +struct ntb_int_info { + struct resource *res; + int rid; + void *tag; +}; + +struct ntb_vec { + struct ntb_softc *ntb; + uint32_t num; + unsigned masked; +}; + +struct ntb_reg { + uint32_t ntb_ctl; + uint32_t lnk_sta; + uint8_t db_size; + unsigned mw_bar[NTB_MAX_BARS]; +}; + +struct ntb_alt_reg { + uint32_t db_bell; + uint32_t db_mask; + uint32_t spad; +}; + +struct ntb_xlat_reg { + uint32_t bar0_base; + uint32_t bar2_base; + uint32_t bar4_base; + uint32_t bar5_base; + + uint32_t bar2_xlat; + uint32_t bar4_xlat; + uint32_t bar5_xlat; + + uint32_t bar2_limit; + uint32_t bar4_limit; + uint32_t bar5_limit; +}; + +struct ntb_b2b_addr { + uint64_t bar0_addr; + uint64_t bar2_addr64; + uint64_t bar4_addr64; + uint64_t bar4_addr32; + uint64_t bar5_addr32; +}; + +struct ntb_msix_data { + uint32_t nmd_ofs; + uint32_t nmd_data; +}; + +struct ntb_softc { + /* ntb.c context. Do not move! Must go first! */ + void *ntb_store; + + device_t device; + enum ntb_device_type type; + uint32_t features; + + struct ntb_pci_bar_info bar_info[NTB_MAX_BARS]; + struct ntb_int_info int_info[MAX_MSIX_INTERRUPTS]; + uint32_t allocated_interrupts; + + struct ntb_msix_data peer_msix_data[XEON_NONLINK_DB_MSIX_BITS]; + struct ntb_msix_data msix_data[XEON_NONLINK_DB_MSIX_BITS]; + bool peer_msix_good; + bool peer_msix_done; + struct ntb_pci_bar_info *peer_lapic_bar; + struct callout peer_msix_work; + + struct callout heartbeat_timer; + struct callout lr_timer; + + struct ntb_vec *msix_vec; + + uint32_t ppd; + enum ntb_conn_type conn_type; + enum ntb_b2b_direction dev_type; + + /* Offset of peer bar0 in B2B BAR */ + uint64_t b2b_off; + /* Memory window used to access peer bar0 */ +#define B2B_MW_DISABLED UINT8_MAX + uint8_t b2b_mw_idx; + uint32_t msix_xlat; + uint8_t msix_mw_idx; + + uint8_t mw_count; + uint8_t spad_count; + uint8_t db_count; + uint8_t db_vec_count; + uint8_t db_vec_shift; + + /* Protects local db_mask. */ +#define DB_MASK_LOCK(sc) mtx_lock_spin(&(sc)->db_mask_lock) +#define DB_MASK_UNLOCK(sc) mtx_unlock_spin(&(sc)->db_mask_lock) +#define DB_MASK_ASSERT(sc,f) mtx_assert(&(sc)->db_mask_lock, (f)) + struct mtx db_mask_lock; + + volatile uint32_t ntb_ctl; + volatile uint32_t lnk_sta; + + uint64_t db_valid_mask; + uint64_t db_link_mask; + uint64_t db_mask; + uint64_t fake_db; /* NTB_SB01BASE_LOCKUP*/ + uint64_t force_db; /* NTB_SB01BASE_LOCKUP*/ + + int last_ts; /* ticks @ last irq */ + + const struct ntb_reg *reg; + const struct ntb_alt_reg *self_reg; + const struct ntb_alt_reg *peer_reg; + const struct ntb_xlat_reg *xlat_reg; +}; + +#ifdef __i386__ +static __inline uint64_t +bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset) +{ + + return (bus_space_read_4(tag, handle, offset) | + ((uint64_t)bus_space_read_4(tag, handle, offset + 4)) << 32); +} + +static __inline void +bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t handle, + bus_size_t offset, uint64_t val) +{ + + bus_space_write_4(tag, handle, offset, val); + bus_space_write_4(tag, handle, offset + 4, val >> 32); +} +#endif + +#define intel_ntb_bar_read(SIZE, bar, offset) \ + bus_space_read_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ + ntb->bar_info[(bar)].pci_bus_handle, (offset)) +#define intel_ntb_bar_write(SIZE, bar, offset, val) \ + bus_space_write_ ## SIZE (ntb->bar_info[(bar)].pci_bus_tag, \ + ntb->bar_info[(bar)].pci_bus_handle, (offset), (val)) +#define intel_ntb_reg_read(SIZE, offset) \ + intel_ntb_bar_read(SIZE, NTB_CONFIG_BAR, offset) +#define intel_ntb_reg_write(SIZE, offset, val) \ + intel_ntb_bar_write(SIZE, NTB_CONFIG_BAR, offset, val) +#define intel_ntb_mw_read(SIZE, offset) \ + intel_ntb_bar_read(SIZE, intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx), \ + offset) +#define intel_ntb_mw_write(SIZE, offset, val) \ + intel_ntb_bar_write(SIZE, intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx), \ + offset, val) + +static int intel_ntb_probe(device_t device); +static int intel_ntb_attach(device_t device); +static int intel_ntb_detach(device_t device); +static uint64_t intel_ntb_db_valid_mask(device_t dev); +static void intel_ntb_spad_clear(device_t dev); +static uint64_t intel_ntb_db_vector_mask(device_t dev, uint32_t vector); +static bool intel_ntb_link_is_up(device_t dev, enum ntb_speed *speed, + enum ntb_width *width); +static int intel_ntb_link_enable(device_t dev, enum ntb_speed speed, + enum ntb_width width); +static int intel_ntb_link_disable(device_t dev); +static int intel_ntb_spad_read(device_t dev, unsigned int idx, uint32_t *val); +static int intel_ntb_peer_spad_write(device_t dev, unsigned int idx, uint32_t val); + +static unsigned intel_ntb_user_mw_to_idx(struct ntb_softc *, unsigned uidx); +static inline enum ntb_bar intel_ntb_mw_to_bar(struct ntb_softc *, unsigned mw); +static inline bool bar_is_64bit(struct ntb_softc *, enum ntb_bar); +static inline void bar_get_xlat_params(struct ntb_softc *, enum ntb_bar, + uint32_t *base, uint32_t *xlat, uint32_t *lmt); +static int intel_ntb_map_pci_bars(struct ntb_softc *ntb); +static int intel_ntb_mw_set_wc_internal(struct ntb_softc *, unsigned idx, + vm_memattr_t); +static void print_map_success(struct ntb_softc *, struct ntb_pci_bar_info *, + const char *); +static int map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar); +static int map_memory_window_bar(struct ntb_softc *ntb, + struct ntb_pci_bar_info *bar); +static void intel_ntb_unmap_pci_bar(struct ntb_softc *ntb); +static int intel_ntb_remap_msix(device_t, uint32_t desired, uint32_t avail); +static int intel_ntb_init_isr(struct ntb_softc *ntb); +static int intel_ntb_setup_legacy_interrupt(struct ntb_softc *ntb); +static int intel_ntb_setup_msix(struct ntb_softc *ntb, uint32_t num_vectors); +static void intel_ntb_teardown_interrupts(struct ntb_softc *ntb); +static inline uint64_t intel_ntb_vec_mask(struct ntb_softc *, uint64_t db_vector); +static void intel_ntb_interrupt(struct ntb_softc *, uint32_t vec); +static void ndev_vec_isr(void *arg); +static void ndev_irq_isr(void *arg); +static inline uint64_t db_ioread(struct ntb_softc *, uint64_t regoff); +static inline void db_iowrite(struct ntb_softc *, uint64_t regoff, uint64_t); +static inline void db_iowrite_raw(struct ntb_softc *, uint64_t regoff, uint64_t); +static int intel_ntb_create_msix_vec(struct ntb_softc *ntb, uint32_t num_vectors); +static void intel_ntb_free_msix_vec(struct ntb_softc *ntb); +static void intel_ntb_get_msix_info(struct ntb_softc *ntb); +static void intel_ntb_exchange_msix(void *); +static struct ntb_hw_info *intel_ntb_get_device_info(uint32_t device_id); +static void intel_ntb_detect_max_mw(struct ntb_softc *ntb); +static int intel_ntb_detect_xeon(struct ntb_softc *ntb); +static int intel_ntb_detect_atom(struct ntb_softc *ntb); +static int intel_ntb_xeon_init_dev(struct ntb_softc *ntb); +static int intel_ntb_atom_init_dev(struct ntb_softc *ntb); +static void intel_ntb_teardown_xeon(struct ntb_softc *ntb); +static void configure_atom_secondary_side_bars(struct ntb_softc *ntb); +static void xeon_reset_sbar_size(struct ntb_softc *, enum ntb_bar idx, + enum ntb_bar regbar); +static void xeon_set_sbar_base_and_limit(struct ntb_softc *, + uint64_t base_addr, enum ntb_bar idx, enum ntb_bar regbar); +static void xeon_set_pbar_xlat(struct ntb_softc *, uint64_t base_addr, + enum ntb_bar idx); +static int xeon_setup_b2b_mw(struct ntb_softc *, + const struct ntb_b2b_addr *addr, const struct ntb_b2b_addr *peer_addr); +static inline bool link_is_up(struct ntb_softc *ntb); +static inline bool _xeon_link_is_up(struct ntb_softc *ntb); +static inline bool atom_link_is_err(struct ntb_softc *ntb); +static inline enum ntb_speed intel_ntb_link_sta_speed(struct ntb_softc *); +static inline enum ntb_width intel_ntb_link_sta_width(struct ntb_softc *); +static void atom_link_hb(void *arg); +static void recover_atom_link(void *arg); +static bool intel_ntb_poll_link(struct ntb_softc *ntb); +static void save_bar_parameters(struct ntb_pci_bar_info *bar); +static void intel_ntb_sysctl_init(struct ntb_softc *); +static int sysctl_handle_features(SYSCTL_HANDLER_ARGS); +static int sysctl_handle_link_admin(SYSCTL_HANDLER_ARGS); +static int sysctl_handle_link_status_human(SYSCTL_HANDLER_ARGS); +static int sysctl_handle_link_status(SYSCTL_HANDLER_ARGS); +static int sysctl_handle_register(SYSCTL_HANDLER_ARGS); + +static unsigned g_ntb_hw_debug_level; +SYSCTL_UINT(_hw_ntb, OID_AUTO, debug_level, CTLFLAG_RWTUN, + &g_ntb_hw_debug_level, 0, "ntb_hw log level -- higher is more verbose"); +#define intel_ntb_printf(lvl, ...) do { \ + if ((lvl) <= g_ntb_hw_debug_level) { \ + device_printf(ntb->device, __VA_ARGS__); \ + } \ +} while (0) + +#define _NTB_PAT_UC 0 +#define _NTB_PAT_WC 1 +#define _NTB_PAT_WT 4 +#define _NTB_PAT_WP 5 +#define _NTB_PAT_WB 6 +#define _NTB_PAT_UCM 7 +static unsigned g_ntb_mw_pat = _NTB_PAT_UC; +SYSCTL_UINT(_hw_ntb, OID_AUTO, default_mw_pat, CTLFLAG_RDTUN, + &g_ntb_mw_pat, 0, "Configure the default memory window cache flags (PAT): " + "UC: " __XSTRING(_NTB_PAT_UC) ", " + "WC: " __XSTRING(_NTB_PAT_WC) ", " + "WT: " __XSTRING(_NTB_PAT_WT) ", " + "WP: " __XSTRING(_NTB_PAT_WP) ", " + "WB: " __XSTRING(_NTB_PAT_WB) ", " + "UC-: " __XSTRING(_NTB_PAT_UCM)); + +static inline vm_memattr_t +intel_ntb_pat_flags(void) +{ + + switch (g_ntb_mw_pat) { + case _NTB_PAT_WC: + return (VM_MEMATTR_WRITE_COMBINING); + case _NTB_PAT_WT: + return (VM_MEMATTR_WRITE_THROUGH); + case _NTB_PAT_WP: + return (VM_MEMATTR_WRITE_PROTECTED); + case _NTB_PAT_WB: + return (VM_MEMATTR_WRITE_BACK); + case _NTB_PAT_UCM: + return (VM_MEMATTR_WEAK_UNCACHEABLE); + case _NTB_PAT_UC: + /* FALLTHROUGH */ + default: + return (VM_MEMATTR_UNCACHEABLE); + } +} + +/* + * Well, this obviously doesn't belong here, but it doesn't seem to exist + * anywhere better yet. + */ +static inline const char * +intel_ntb_vm_memattr_to_str(vm_memattr_t pat) +{ + + switch (pat) { + case VM_MEMATTR_WRITE_COMBINING: + return ("WRITE_COMBINING"); + case VM_MEMATTR_WRITE_THROUGH: + return ("WRITE_THROUGH"); + case VM_MEMATTR_WRITE_PROTECTED: + return ("WRITE_PROTECTED"); + case VM_MEMATTR_WRITE_BACK: + return ("WRITE_BACK"); + case VM_MEMATTR_WEAK_UNCACHEABLE: + return ("UNCACHED"); + case VM_MEMATTR_UNCACHEABLE: + return ("UNCACHEABLE"); + default: + return ("UNKNOWN"); + } +} + +static int g_ntb_msix_idx = 1; +SYSCTL_INT(_hw_ntb, OID_AUTO, msix_mw_idx, CTLFLAG_RDTUN, &g_ntb_msix_idx, + 0, "Use this memory window to access the peer MSIX message complex on " + "certain Xeon-based NTB systems, as a workaround for a hardware errata. " + "Like b2b_mw_idx, negative values index from the last available memory " + "window. (Applies on Xeon platforms with SB01BASE_LOCKUP errata.)"); + +static int g_ntb_mw_idx = -1; +SYSCTL_INT(_hw_ntb, OID_AUTO, b2b_mw_idx, CTLFLAG_RDTUN, &g_ntb_mw_idx, + 0, "Use this memory window to access the peer NTB registers. A " + "non-negative value starts from the first MW index; a negative value " + "starts from the last MW index. The default is -1, i.e., the last " + "available memory window. Both sides of the NTB MUST set the same " + "value here! (Applies on Xeon platforms with SDOORBELL_LOCKUP errata.)"); + +/* Hardware owns the low 16 bits of features. */ +#define NTB_BAR_SIZE_4K (1 << 0) +#define NTB_SDOORBELL_LOCKUP (1 << 1) +#define NTB_SB01BASE_LOCKUP (1 << 2) +#define NTB_B2BDOORBELL_BIT14 (1 << 3) +/* Software/configuration owns the top 16 bits. */ +#define NTB_SPLIT_BAR (1ull << 16) + +#define NTB_FEATURES_STR \ + "\20\21SPLIT_BAR4\04B2B_DOORBELL_BIT14\03SB01BASE_LOCKUP" \ + "\02SDOORBELL_LOCKUP\01BAR_SIZE_4K" + +static struct ntb_hw_info pci_ids[] = { + /* XXX: PS/SS IDs left out until they are supported. */ + { 0x0C4E8086, "BWD Atom Processor S1200 Non-Transparent Bridge B2B", + NTB_ATOM, 0 }, + + { 0x37258086, "JSF Xeon C35xx/C55xx Non-Transparent Bridge B2B", + NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 }, + { 0x3C0D8086, "SNB Xeon E5/Core i7 Non-Transparent Bridge B2B", + NTB_XEON, NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 }, + { 0x0E0D8086, "IVT Xeon E5 V2 Non-Transparent Bridge B2B", NTB_XEON, + NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | + NTB_SB01BASE_LOCKUP | NTB_BAR_SIZE_4K }, + { 0x2F0D8086, "HSX Xeon E5 V3 Non-Transparent Bridge B2B", NTB_XEON, + NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | + NTB_SB01BASE_LOCKUP }, + { 0x6F0D8086, "BDX Xeon E5 V4 Non-Transparent Bridge B2B", NTB_XEON, + NTB_SDOORBELL_LOCKUP | NTB_B2BDOORBELL_BIT14 | + NTB_SB01BASE_LOCKUP }, + + { 0x00000000, NULL, NTB_ATOM, 0 } +}; + +static const struct ntb_reg atom_reg = { + .ntb_ctl = ATOM_NTBCNTL_OFFSET, + .lnk_sta = ATOM_LINK_STATUS_OFFSET, + .db_size = sizeof(uint64_t), + .mw_bar = { NTB_B2B_BAR_1, NTB_B2B_BAR_2 }, +}; + +static const struct ntb_alt_reg atom_pri_reg = { + .db_bell = ATOM_PDOORBELL_OFFSET, + .db_mask = ATOM_PDBMSK_OFFSET, + .spad = ATOM_SPAD_OFFSET, +}; + +static const struct ntb_alt_reg atom_b2b_reg = { + .db_bell = ATOM_B2B_DOORBELL_OFFSET, + .spad = ATOM_B2B_SPAD_OFFSET, +}; + +static const struct ntb_xlat_reg atom_sec_xlat = { +#if 0 + /* "FIXME" says the Linux driver. */ + .bar0_base = ATOM_SBAR0BASE_OFFSET, + .bar2_base = ATOM_SBAR2BASE_OFFSET, + .bar4_base = ATOM_SBAR4BASE_OFFSET, + + .bar2_limit = ATOM_SBAR2LMT_OFFSET, + .bar4_limit = ATOM_SBAR4LMT_OFFSET, +#endif + + .bar2_xlat = ATOM_SBAR2XLAT_OFFSET, + .bar4_xlat = ATOM_SBAR4XLAT_OFFSET, +}; + +static const struct ntb_reg xeon_reg = { + .ntb_ctl = XEON_NTBCNTL_OFFSET, + .lnk_sta = XEON_LINK_STATUS_OFFSET, + .db_size = sizeof(uint16_t), + .mw_bar = { NTB_B2B_BAR_1, NTB_B2B_BAR_2, NTB_B2B_BAR_3 }, +}; + +static const struct ntb_alt_reg xeon_pri_reg = { + .db_bell = XEON_PDOORBELL_OFFSET, + .db_mask = XEON_PDBMSK_OFFSET, + .spad = XEON_SPAD_OFFSET, +}; + +static const struct ntb_alt_reg xeon_b2b_reg = { + .db_bell = XEON_B2B_DOORBELL_OFFSET, + .spad = XEON_B2B_SPAD_OFFSET, +}; + +static const struct ntb_xlat_reg xeon_sec_xlat = { + .bar0_base = XEON_SBAR0BASE_OFFSET, + .bar2_base = XEON_SBAR2BASE_OFFSET, + .bar4_base = XEON_SBAR4BASE_OFFSET, + .bar5_base = XEON_SBAR5BASE_OFFSET, + + .bar2_limit = XEON_SBAR2LMT_OFFSET, + .bar4_limit = XEON_SBAR4LMT_OFFSET, + .bar5_limit = XEON_SBAR5LMT_OFFSET, + + .bar2_xlat = XEON_SBAR2XLAT_OFFSET, + .bar4_xlat = XEON_SBAR4XLAT_OFFSET, + .bar5_xlat = XEON_SBAR5XLAT_OFFSET, +}; + +static struct ntb_b2b_addr xeon_b2b_usd_addr = { + .bar0_addr = XEON_B2B_BAR0_ADDR, + .bar2_addr64 = XEON_B2B_BAR2_ADDR64, + .bar4_addr64 = XEON_B2B_BAR4_ADDR64, + .bar4_addr32 = XEON_B2B_BAR4_ADDR32, + .bar5_addr32 = XEON_B2B_BAR5_ADDR32, +}; + +static struct ntb_b2b_addr xeon_b2b_dsd_addr = { + .bar0_addr = XEON_B2B_BAR0_ADDR, + .bar2_addr64 = XEON_B2B_BAR2_ADDR64, + .bar4_addr64 = XEON_B2B_BAR4_ADDR64, + .bar4_addr32 = XEON_B2B_BAR4_ADDR32, + .bar5_addr32 = XEON_B2B_BAR5_ADDR32, +}; + +SYSCTL_NODE(_hw_ntb, OID_AUTO, xeon_b2b, CTLFLAG_RW, 0, + "B2B MW segment overrides -- MUST be the same on both sides"); + +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar2_addr64, CTLFLAG_RDTUN, + &xeon_b2b_usd_addr.bar2_addr64, 0, "If using B2B topology on Xeon " + "hardware, use this 64-bit address on the bus between the NTB devices for " + "the window at BAR2, on the upstream side of the link. MUST be the same " + "address on both sides."); +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar4_addr64, CTLFLAG_RDTUN, + &xeon_b2b_usd_addr.bar4_addr64, 0, "See usd_bar2_addr64, but BAR4."); +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar4_addr32, CTLFLAG_RDTUN, + &xeon_b2b_usd_addr.bar4_addr32, 0, "See usd_bar2_addr64, but BAR4 " + "(split-BAR mode)."); +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, usd_bar5_addr32, CTLFLAG_RDTUN, + &xeon_b2b_usd_addr.bar5_addr32, 0, "See usd_bar2_addr64, but BAR5 " + "(split-BAR mode)."); + +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar2_addr64, CTLFLAG_RDTUN, + &xeon_b2b_dsd_addr.bar2_addr64, 0, "If using B2B topology on Xeon " + "hardware, use this 64-bit address on the bus between the NTB devices for " + "the window at BAR2, on the downstream side of the link. MUST be the same" + " address on both sides."); +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar4_addr64, CTLFLAG_RDTUN, + &xeon_b2b_dsd_addr.bar4_addr64, 0, "See dsd_bar2_addr64, but BAR4."); +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar4_addr32, CTLFLAG_RDTUN, + &xeon_b2b_dsd_addr.bar4_addr32, 0, "See dsd_bar2_addr64, but BAR4 " + "(split-BAR mode)."); +SYSCTL_UQUAD(_hw_ntb_xeon_b2b, OID_AUTO, dsd_bar5_addr32, CTLFLAG_RDTUN, + &xeon_b2b_dsd_addr.bar5_addr32, 0, "See dsd_bar2_addr64, but BAR5 " + "(split-BAR mode)."); + +/* + * OS <-> Driver interface structures + */ +MALLOC_DEFINE(M_NTB, "ntb_hw", "ntb_hw driver memory allocations"); + +/* + * OS <-> Driver linkage functions + */ +static int +intel_ntb_probe(device_t device) +{ + struct ntb_hw_info *p; + + p = intel_ntb_get_device_info(pci_get_devid(device)); + if (p == NULL) + return (ENXIO); + + device_set_desc(device, p->desc); + return (0); +} + +static int +intel_ntb_attach(device_t device) +{ + struct ntb_softc *ntb; + struct ntb_hw_info *p; + int error; + + ntb = device_get_softc(device); + p = intel_ntb_get_device_info(pci_get_devid(device)); + + ntb->device = device; + ntb->type = p->type; + ntb->features = p->features; + ntb->b2b_mw_idx = B2B_MW_DISABLED; + ntb->msix_mw_idx = B2B_MW_DISABLED; + + /* Heartbeat timer for NTB_ATOM since there is no link interrupt */ + callout_init(&ntb->heartbeat_timer, 1); + callout_init(&ntb->lr_timer, 1); + callout_init(&ntb->peer_msix_work, 1); + mtx_init(&ntb->db_mask_lock, "ntb hw bits", NULL, MTX_SPIN); + + if (ntb->type == NTB_ATOM) + error = intel_ntb_detect_atom(ntb); + else + error = intel_ntb_detect_xeon(ntb); + if (error != 0) + goto out; + + intel_ntb_detect_max_mw(ntb); + + pci_enable_busmaster(ntb->device); + + error = intel_ntb_map_pci_bars(ntb); + if (error != 0) + goto out; + if (ntb->type == NTB_ATOM) + error = intel_ntb_atom_init_dev(ntb); + else + error = intel_ntb_xeon_init_dev(ntb); + if (error != 0) + goto out; + + intel_ntb_spad_clear(device); + + intel_ntb_poll_link(ntb); + + intel_ntb_sysctl_init(ntb); + + /* Attach children to this controller */ + error = ntb_register_device(device); + +out: + if (error != 0) + intel_ntb_detach(device); + return (error); +} + +static int +intel_ntb_detach(device_t device) +{ + struct ntb_softc *ntb; + + ntb = device_get_softc(device); + + /* Detach & delete all children */ + ntb_unregister_device(device); + + if (ntb->self_reg != NULL) { + DB_MASK_LOCK(ntb); + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_valid_mask); + DB_MASK_UNLOCK(ntb); + } + callout_drain(&ntb->heartbeat_timer); + callout_drain(&ntb->lr_timer); + callout_drain(&ntb->peer_msix_work); + pci_disable_busmaster(ntb->device); + if (ntb->type == NTB_XEON) + intel_ntb_teardown_xeon(ntb); + intel_ntb_teardown_interrupts(ntb); + + mtx_destroy(&ntb->db_mask_lock); + + intel_ntb_unmap_pci_bar(ntb); + + return (0); +} + +/* + * Driver internal routines + */ +static inline enum ntb_bar +intel_ntb_mw_to_bar(struct ntb_softc *ntb, unsigned mw) +{ + + KASSERT(mw < ntb->mw_count, + ("%s: mw:%u > count:%u", __func__, mw, (unsigned)ntb->mw_count)); + KASSERT(ntb->reg->mw_bar[mw] != 0, ("invalid mw")); + + return (ntb->reg->mw_bar[mw]); +} + +static inline bool +bar_is_64bit(struct ntb_softc *ntb, enum ntb_bar bar) +{ + /* XXX This assertion could be stronger. */ + KASSERT(bar < NTB_MAX_BARS, ("bogus bar")); + return (bar < NTB_B2B_BAR_2 || !HAS_FEATURE(ntb, NTB_SPLIT_BAR)); +} + +static inline void +bar_get_xlat_params(struct ntb_softc *ntb, enum ntb_bar bar, uint32_t *base, + uint32_t *xlat, uint32_t *lmt) +{ + uint32_t basev, lmtv, xlatv; + + switch (bar) { + case NTB_B2B_BAR_1: + basev = ntb->xlat_reg->bar2_base; + lmtv = ntb->xlat_reg->bar2_limit; + xlatv = ntb->xlat_reg->bar2_xlat; + break; + case NTB_B2B_BAR_2: + basev = ntb->xlat_reg->bar4_base; + lmtv = ntb->xlat_reg->bar4_limit; + xlatv = ntb->xlat_reg->bar4_xlat; + break; + case NTB_B2B_BAR_3: + basev = ntb->xlat_reg->bar5_base; + lmtv = ntb->xlat_reg->bar5_limit; + xlatv = ntb->xlat_reg->bar5_xlat; + break; + default: + KASSERT(bar >= NTB_B2B_BAR_1 && bar < NTB_MAX_BARS, + ("bad bar")); + basev = lmtv = xlatv = 0; + break; + } + + if (base != NULL) + *base = basev; + if (xlat != NULL) + *xlat = xlatv; + if (lmt != NULL) + *lmt = lmtv; +} + +static int +intel_ntb_map_pci_bars(struct ntb_softc *ntb) +{ + int rc; + + ntb->bar_info[NTB_CONFIG_BAR].pci_resource_id = PCIR_BAR(0); + rc = map_mmr_bar(ntb, &ntb->bar_info[NTB_CONFIG_BAR]); + if (rc != 0) + goto out; + + ntb->bar_info[NTB_B2B_BAR_1].pci_resource_id = PCIR_BAR(2); + rc = map_memory_window_bar(ntb, &ntb->bar_info[NTB_B2B_BAR_1]); + if (rc != 0) + goto out; + ntb->bar_info[NTB_B2B_BAR_1].psz_off = XEON_PBAR23SZ_OFFSET; + ntb->bar_info[NTB_B2B_BAR_1].ssz_off = XEON_SBAR23SZ_OFFSET; + ntb->bar_info[NTB_B2B_BAR_1].pbarxlat_off = XEON_PBAR2XLAT_OFFSET; + + ntb->bar_info[NTB_B2B_BAR_2].pci_resource_id = PCIR_BAR(4); + rc = map_memory_window_bar(ntb, &ntb->bar_info[NTB_B2B_BAR_2]); + if (rc != 0) + goto out; + ntb->bar_info[NTB_B2B_BAR_2].psz_off = XEON_PBAR4SZ_OFFSET; + ntb->bar_info[NTB_B2B_BAR_2].ssz_off = XEON_SBAR4SZ_OFFSET; + ntb->bar_info[NTB_B2B_BAR_2].pbarxlat_off = XEON_PBAR4XLAT_OFFSET; + + if (!HAS_FEATURE(ntb, NTB_SPLIT_BAR)) + goto out; + + ntb->bar_info[NTB_B2B_BAR_3].pci_resource_id = PCIR_BAR(5); + rc = map_memory_window_bar(ntb, &ntb->bar_info[NTB_B2B_BAR_3]); + ntb->bar_info[NTB_B2B_BAR_3].psz_off = XEON_PBAR5SZ_OFFSET; + ntb->bar_info[NTB_B2B_BAR_3].ssz_off = XEON_SBAR5SZ_OFFSET; + ntb->bar_info[NTB_B2B_BAR_3].pbarxlat_off = XEON_PBAR5XLAT_OFFSET; + +out: + if (rc != 0) + device_printf(ntb->device, + "unable to allocate pci resource\n"); + return (rc); +} + +static void +print_map_success(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar, + const char *kind) +{ + + device_printf(ntb->device, + "Mapped BAR%d v:[%p-%p] p:[%p-%p] (0x%jx bytes) (%s)\n", + PCI_RID2BAR(bar->pci_resource_id), bar->vbase, + (char *)bar->vbase + bar->size - 1, + (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), + (uintmax_t)bar->size, kind); +} + +static int +map_mmr_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) +{ + + bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, + &bar->pci_resource_id, RF_ACTIVE); + if (bar->pci_resource == NULL) + return (ENXIO); + + save_bar_parameters(bar); + bar->map_mode = VM_MEMATTR_UNCACHEABLE; + print_map_success(ntb, bar, "mmr"); + return (0); +} + +static int +map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar) +{ + int rc; + vm_memattr_t mapmode; + uint8_t bar_size_bits = 0; + + bar->pci_resource = bus_alloc_resource_any(ntb->device, SYS_RES_MEMORY, + &bar->pci_resource_id, RF_ACTIVE); + + if (bar->pci_resource == NULL) + return (ENXIO); + + save_bar_parameters(bar); + /* + * Ivytown NTB BAR sizes are misreported by the hardware due to a + * hardware issue. To work around this, query the size it should be + * configured to by the device and modify the resource to correspond to + * this new size. The BIOS on systems with this problem is required to + * provide enough address space to allow the driver to make this change + * safely. + * + * Ideally I could have just specified the size when I allocated the + * resource like: + * bus_alloc_resource(ntb->device, + * SYS_RES_MEMORY, &bar->pci_resource_id, 0ul, ~0ul, + * 1ul << bar_size_bits, RF_ACTIVE); + * but the PCI driver does not honor the size in this call, so we have + * to modify it after the fact. + */ + if (HAS_FEATURE(ntb, NTB_BAR_SIZE_4K)) { + if (bar->pci_resource_id == PCIR_BAR(2)) + bar_size_bits = pci_read_config(ntb->device, + XEON_PBAR23SZ_OFFSET, 1); + else + bar_size_bits = pci_read_config(ntb->device, + XEON_PBAR45SZ_OFFSET, 1); + + rc = bus_adjust_resource(ntb->device, SYS_RES_MEMORY, + bar->pci_resource, bar->pbase, + bar->pbase + (1ul << bar_size_bits) - 1); + if (rc != 0) { + device_printf(ntb->device, + "unable to resize bar\n"); + return (rc); + } + + save_bar_parameters(bar); + } + + bar->map_mode = VM_MEMATTR_UNCACHEABLE; + print_map_success(ntb, bar, "mw"); + + /* + * Optionally, mark MW BARs as anything other than UC to improve + * performance. + */ + mapmode = intel_ntb_pat_flags(); + if (mapmode == bar->map_mode) + return (0); + + rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mapmode); + if (rc == 0) { + bar->map_mode = mapmode; + device_printf(ntb->device, + "Marked BAR%d v:[%p-%p] p:[%p-%p] as " + "%s.\n", + PCI_RID2BAR(bar->pci_resource_id), bar->vbase, + (char *)bar->vbase + bar->size - 1, + (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), + intel_ntb_vm_memattr_to_str(mapmode)); + } else + device_printf(ntb->device, + "Unable to mark BAR%d v:[%p-%p] p:[%p-%p] as " + "%s: %d\n", + PCI_RID2BAR(bar->pci_resource_id), bar->vbase, + (char *)bar->vbase + bar->size - 1, + (void *)bar->pbase, (void *)(bar->pbase + bar->size - 1), + intel_ntb_vm_memattr_to_str(mapmode), rc); + /* Proceed anyway */ + return (0); +} + +static void +intel_ntb_unmap_pci_bar(struct ntb_softc *ntb) +{ + struct ntb_pci_bar_info *current_bar; + int i; + + for (i = 0; i < NTB_MAX_BARS; i++) { + current_bar = &ntb->bar_info[i]; + if (current_bar->pci_resource != NULL) + bus_release_resource(ntb->device, SYS_RES_MEMORY, + current_bar->pci_resource_id, + current_bar->pci_resource); + } +} + +static int +intel_ntb_setup_msix(struct ntb_softc *ntb, uint32_t num_vectors) +{ + uint32_t i; + int rc; + + for (i = 0; i < num_vectors; i++) { + ntb->int_info[i].rid = i + 1; + ntb->int_info[i].res = bus_alloc_resource_any(ntb->device, + SYS_RES_IRQ, &ntb->int_info[i].rid, RF_ACTIVE); + if (ntb->int_info[i].res == NULL) { + device_printf(ntb->device, + "bus_alloc_resource failed\n"); + return (ENOMEM); + } + ntb->int_info[i].tag = NULL; + ntb->allocated_interrupts++; + rc = bus_setup_intr(ntb->device, ntb->int_info[i].res, + INTR_MPSAFE | INTR_TYPE_MISC, NULL, ndev_vec_isr, + &ntb->msix_vec[i], &ntb->int_info[i].tag); + if (rc != 0) { + device_printf(ntb->device, "bus_setup_intr failed\n"); + return (ENXIO); + } + } + return (0); +} + +/* + * The Linux NTB driver drops from MSI-X to legacy INTx if a unique vector + * cannot be allocated for each MSI-X message. JHB seems to think remapping + * should be okay. This tunable should enable us to test that hypothesis + * when someone gets their hands on some Xeon hardware. + */ +static int ntb_force_remap_mode; +SYSCTL_INT(_hw_ntb, OID_AUTO, force_remap_mode, CTLFLAG_RDTUN, + &ntb_force_remap_mode, 0, "If enabled, force MSI-X messages to be remapped" + " to a smaller number of ithreads, even if the desired number are " + "available"); + +/* + * In case it is NOT ok, give consumers an abort button. + */ +static int ntb_prefer_intx; +SYSCTL_INT(_hw_ntb, OID_AUTO, prefer_intx_to_remap, CTLFLAG_RDTUN, + &ntb_prefer_intx, 0, "If enabled, prefer to use legacy INTx mode rather " + "than remapping MSI-X messages over available slots (match Linux driver " + "behavior)"); + +/* + * Remap the desired number of MSI-X messages to available ithreads in a simple + * round-robin fashion. + */ +static int +intel_ntb_remap_msix(device_t dev, uint32_t desired, uint32_t avail) +{ + u_int *vectors; + uint32_t i; + int rc; + + if (ntb_prefer_intx != 0) + return (ENXIO); + + vectors = malloc(desired * sizeof(*vectors), M_NTB, M_ZERO | M_WAITOK); + + for (i = 0; i < desired; i++) + vectors[i] = (i % avail) + 1; + + rc = pci_remap_msix(dev, desired, vectors); + free(vectors, M_NTB); + return (rc); +} + +static int +intel_ntb_init_isr(struct ntb_softc *ntb) +{ + uint32_t desired_vectors, num_vectors; + int rc; + + ntb->allocated_interrupts = 0; + ntb->last_ts = ticks; + + /* + * Mask all doorbell interrupts. (Except link events!) + */ + DB_MASK_LOCK(ntb); + ntb->db_mask = ntb->db_valid_mask; + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); + DB_MASK_UNLOCK(ntb); + + num_vectors = desired_vectors = MIN(pci_msix_count(ntb->device), + ntb->db_count); + if (desired_vectors >= 1) { + rc = pci_alloc_msix(ntb->device, &num_vectors); + + if (ntb_force_remap_mode != 0 && rc == 0 && + num_vectors == desired_vectors) + num_vectors--; + + if (rc == 0 && num_vectors < desired_vectors) { + rc = intel_ntb_remap_msix(ntb->device, desired_vectors, + num_vectors); + if (rc == 0) + num_vectors = desired_vectors; + else + pci_release_msi(ntb->device); + } + if (rc != 0) + num_vectors = 1; + } else + num_vectors = 1; + + if (ntb->type == NTB_XEON && num_vectors < ntb->db_vec_count) { + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + device_printf(ntb->device, + "Errata workaround does not support MSI or INTX\n"); + return (EINVAL); + } + + ntb->db_vec_count = 1; + ntb->db_vec_shift = XEON_DB_TOTAL_SHIFT; + rc = intel_ntb_setup_legacy_interrupt(ntb); + } else { + if (num_vectors - 1 != XEON_NONLINK_DB_MSIX_BITS && + HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + device_printf(ntb->device, + "Errata workaround expects %d doorbell bits\n", + XEON_NONLINK_DB_MSIX_BITS); + return (EINVAL); + } + + intel_ntb_create_msix_vec(ntb, num_vectors); + rc = intel_ntb_setup_msix(ntb, num_vectors); + } + if (rc != 0) { + device_printf(ntb->device, + "Error allocating interrupts: %d\n", rc); + intel_ntb_free_msix_vec(ntb); + } + + return (rc); +} + +static int +intel_ntb_setup_legacy_interrupt(struct ntb_softc *ntb) +{ + int rc; + + ntb->int_info[0].rid = 0; + ntb->int_info[0].res = bus_alloc_resource_any(ntb->device, SYS_RES_IRQ, + &ntb->int_info[0].rid, RF_SHAREABLE|RF_ACTIVE); + if (ntb->int_info[0].res == NULL) { + device_printf(ntb->device, "bus_alloc_resource failed\n"); + return (ENOMEM); + } + + ntb->int_info[0].tag = NULL; + ntb->allocated_interrupts = 1; + + rc = bus_setup_intr(ntb->device, ntb->int_info[0].res, + INTR_MPSAFE | INTR_TYPE_MISC, NULL, ndev_irq_isr, + ntb, &ntb->int_info[0].tag); + if (rc != 0) { + device_printf(ntb->device, "bus_setup_intr failed\n"); + return (ENXIO); + } + + return (0); +} + +static void +intel_ntb_teardown_interrupts(struct ntb_softc *ntb) +{ + struct ntb_int_info *current_int; + int i; + + for (i = 0; i < ntb->allocated_interrupts; i++) { + current_int = &ntb->int_info[i]; + if (current_int->tag != NULL) + bus_teardown_intr(ntb->device, current_int->res, + current_int->tag); + + if (current_int->res != NULL) + bus_release_resource(ntb->device, SYS_RES_IRQ, + rman_get_rid(current_int->res), current_int->res); + } + + intel_ntb_free_msix_vec(ntb); + pci_release_msi(ntb->device); +} + +/* + * Doorbell register and mask are 64-bit on Atom, 16-bit on Xeon. Abstract it + * out to make code clearer. + */ +static inline uint64_t +db_ioread(struct ntb_softc *ntb, uint64_t regoff) +{ + + if (ntb->type == NTB_ATOM) + return (intel_ntb_reg_read(8, regoff)); + + KASSERT(ntb->type == NTB_XEON, ("bad ntb type")); + + return (intel_ntb_reg_read(2, regoff)); +} + +static inline void +db_iowrite(struct ntb_softc *ntb, uint64_t regoff, uint64_t val) +{ + + KASSERT((val & ~ntb->db_valid_mask) == 0, + ("%s: Invalid bits 0x%jx (valid: 0x%jx)", __func__, + (uintmax_t)(val & ~ntb->db_valid_mask), + (uintmax_t)ntb->db_valid_mask)); + + if (regoff == ntb->self_reg->db_mask) + DB_MASK_ASSERT(ntb, MA_OWNED); + db_iowrite_raw(ntb, regoff, val); +} + +static inline void +db_iowrite_raw(struct ntb_softc *ntb, uint64_t regoff, uint64_t val) +{ + + if (ntb->type == NTB_ATOM) { + intel_ntb_reg_write(8, regoff, val); + return; + } + + KASSERT(ntb->type == NTB_XEON, ("bad ntb type")); + intel_ntb_reg_write(2, regoff, (uint16_t)val); +} + +static void +intel_ntb_db_set_mask(device_t dev, uint64_t bits) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + DB_MASK_LOCK(ntb); + ntb->db_mask |= bits; + if (!HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); + DB_MASK_UNLOCK(ntb); +} + +static void +intel_ntb_db_clear_mask(device_t dev, uint64_t bits) +{ + struct ntb_softc *ntb = device_get_softc(dev); + uint64_t ibits; + int i; + + KASSERT((bits & ~ntb->db_valid_mask) == 0, + ("%s: Invalid bits 0x%jx (valid: 0x%jx)", __func__, + (uintmax_t)(bits & ~ntb->db_valid_mask), + (uintmax_t)ntb->db_valid_mask)); + + DB_MASK_LOCK(ntb); + ibits = ntb->fake_db & ntb->db_mask & bits; + ntb->db_mask &= ~bits; + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + /* Simulate fake interrupts if unmasked DB bits are set. */ + ntb->force_db |= ibits; + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + if ((ibits & intel_ntb_db_vector_mask(dev, i)) != 0) + swi_sched(ntb->int_info[i].tag, 0); + } + } else { + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); + } + DB_MASK_UNLOCK(ntb); +} + +static uint64_t +intel_ntb_db_read(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) + return (ntb->fake_db); + + return (db_ioread(ntb, ntb->self_reg->db_bell)); +} + +static void +intel_ntb_db_clear(device_t dev, uint64_t bits) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + KASSERT((bits & ~ntb->db_valid_mask) == 0, + ("%s: Invalid bits 0x%jx (valid: 0x%jx)", __func__, + (uintmax_t)(bits & ~ntb->db_valid_mask), + (uintmax_t)ntb->db_valid_mask)); + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + DB_MASK_LOCK(ntb); + ntb->fake_db &= ~bits; + DB_MASK_UNLOCK(ntb); + return; + } + + db_iowrite(ntb, ntb->self_reg->db_bell, bits); +} + +static inline uint64_t +intel_ntb_vec_mask(struct ntb_softc *ntb, uint64_t db_vector) +{ + uint64_t shift, mask; + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + /* + * Remap vectors in custom way to make at least first + * three doorbells to not generate stray events. + * This breaks Linux compatibility (if one existed) + * when more then one DB is used (not by if_ntb). + */ + if (db_vector < XEON_NONLINK_DB_MSIX_BITS - 1) + return (1 << db_vector); + if (db_vector == XEON_NONLINK_DB_MSIX_BITS - 1) + return (0x7ffc); + } + + shift = ntb->db_vec_shift; + mask = (1ull << shift) - 1; + return (mask << (shift * db_vector)); +} + +static void +intel_ntb_interrupt(struct ntb_softc *ntb, uint32_t vec) +{ + uint64_t vec_mask; + + ntb->last_ts = ticks; + vec_mask = intel_ntb_vec_mask(ntb, vec); + + if ((vec_mask & ntb->db_link_mask) != 0) { + if (intel_ntb_poll_link(ntb)) + ntb_link_event(ntb->device); + } + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP) && + (vec_mask & ntb->db_link_mask) == 0) { + DB_MASK_LOCK(ntb); + + /* + * Do not report same DB events again if not cleared yet, + * unless the mask was just cleared for them and this + * interrupt handler call can be the consequence of it. + */ + vec_mask &= ~ntb->fake_db | ntb->force_db; + ntb->force_db &= ~vec_mask; + + /* Update our internal doorbell register. */ + ntb->fake_db |= vec_mask; + + /* Do not report masked DB events. */ + vec_mask &= ~ntb->db_mask; + + DB_MASK_UNLOCK(ntb); + } + + if ((vec_mask & ntb->db_valid_mask) != 0) + ntb_db_event(ntb->device, vec); +} + +static void +ndev_vec_isr(void *arg) +{ + struct ntb_vec *nvec = arg; + + intel_ntb_interrupt(nvec->ntb, nvec->num); +} + +static void +ndev_irq_isr(void *arg) +{ + /* If we couldn't set up MSI-X, we only have the one vector. */ + intel_ntb_interrupt(arg, 0); +} + +static int +intel_ntb_create_msix_vec(struct ntb_softc *ntb, uint32_t num_vectors) +{ + uint32_t i; + + ntb->msix_vec = malloc(num_vectors * sizeof(*ntb->msix_vec), M_NTB, + M_ZERO | M_WAITOK); + for (i = 0; i < num_vectors; i++) { + ntb->msix_vec[i].num = i; + ntb->msix_vec[i].ntb = ntb; + } + + return (0); +} + +static void +intel_ntb_free_msix_vec(struct ntb_softc *ntb) +{ + + if (ntb->msix_vec == NULL) + return; + + free(ntb->msix_vec, M_NTB); + ntb->msix_vec = NULL; +} + +static void +intel_ntb_get_msix_info(struct ntb_softc *ntb) +{ + struct pci_devinfo *dinfo; + struct pcicfg_msix *msix; + uint32_t laddr, data, i, offset; + + dinfo = device_get_ivars(ntb->device); + msix = &dinfo->cfg.msix; + + CTASSERT(XEON_NONLINK_DB_MSIX_BITS == nitems(ntb->msix_data)); + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + offset = msix->msix_table_offset + i * PCI_MSIX_ENTRY_SIZE; + + laddr = bus_read_4(msix->msix_table_res, offset + + PCI_MSIX_ENTRY_LOWER_ADDR); + intel_ntb_printf(2, "local MSIX addr(%u): 0x%x\n", i, laddr); + + KASSERT((laddr & MSI_INTEL_ADDR_BASE) == MSI_INTEL_ADDR_BASE, + ("local MSIX addr 0x%x not in MSI base 0x%x", laddr, + MSI_INTEL_ADDR_BASE)); + ntb->msix_data[i].nmd_ofs = laddr; + + data = bus_read_4(msix->msix_table_res, offset + + PCI_MSIX_ENTRY_DATA); + intel_ntb_printf(2, "local MSIX data(%u): 0x%x\n", i, data); + + ntb->msix_data[i].nmd_data = data; + } +} + +static struct ntb_hw_info * +intel_ntb_get_device_info(uint32_t device_id) +{ + struct ntb_hw_info *ep = pci_ids; + + while (ep->device_id) { + if (ep->device_id == device_id) + return (ep); + ++ep; + } + return (NULL); +} + +static void +intel_ntb_teardown_xeon(struct ntb_softc *ntb) +{ + + if (ntb->reg != NULL) + intel_ntb_link_disable(ntb->device); +} + +static void +intel_ntb_detect_max_mw(struct ntb_softc *ntb) +{ + + if (ntb->type == NTB_ATOM) { + ntb->mw_count = ATOM_MW_COUNT; + return; + } + + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) + ntb->mw_count = XEON_HSX_SPLIT_MW_COUNT; + else + ntb->mw_count = XEON_SNB_MW_COUNT; +} + +static int +intel_ntb_detect_xeon(struct ntb_softc *ntb) +{ + uint8_t ppd, conn_type; + + ppd = pci_read_config(ntb->device, NTB_PPD_OFFSET, 1); + ntb->ppd = ppd; + + if ((ppd & XEON_PPD_DEV_TYPE) != 0) + ntb->dev_type = NTB_DEV_DSD; + else + ntb->dev_type = NTB_DEV_USD; + + if ((ppd & XEON_PPD_SPLIT_BAR) != 0) + ntb->features |= NTB_SPLIT_BAR; + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP) && + !HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + device_printf(ntb->device, + "Can not apply SB01BASE_LOCKUP workaround " + "with split BARs disabled!\n"); + device_printf(ntb->device, + "Expect system hangs under heavy NTB traffic!\n"); + ntb->features &= ~NTB_SB01BASE_LOCKUP; + } + + /* + * SDOORBELL errata workaround gets in the way of SB01BASE_LOCKUP + * errata workaround; only do one at a time. + */ + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) + ntb->features &= ~NTB_SDOORBELL_LOCKUP; + + conn_type = ppd & XEON_PPD_CONN_TYPE; + switch (conn_type) { + case NTB_CONN_B2B: + ntb->conn_type = conn_type; + break; + case NTB_CONN_RP: + case NTB_CONN_TRANSPARENT: + default: + device_printf(ntb->device, "Unsupported connection type: %u\n", + (unsigned)conn_type); + return (ENXIO); + } + return (0); +} + +static int +intel_ntb_detect_atom(struct ntb_softc *ntb) +{ + uint32_t ppd, conn_type; + + ppd = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4); + ntb->ppd = ppd; + + if ((ppd & ATOM_PPD_DEV_TYPE) != 0) + ntb->dev_type = NTB_DEV_DSD; + else + ntb->dev_type = NTB_DEV_USD; + + conn_type = (ppd & ATOM_PPD_CONN_TYPE) >> 8; + switch (conn_type) { + case NTB_CONN_B2B: + ntb->conn_type = conn_type; + break; + default: + device_printf(ntb->device, "Unsupported NTB configuration\n"); + return (ENXIO); + } + return (0); +} + +static int +intel_ntb_xeon_init_dev(struct ntb_softc *ntb) +{ + int rc; + + ntb->spad_count = XEON_SPAD_COUNT; + ntb->db_count = XEON_DB_COUNT; + ntb->db_link_mask = XEON_DB_LINK_BIT; + ntb->db_vec_count = XEON_DB_MSIX_VECTOR_COUNT; + ntb->db_vec_shift = XEON_DB_MSIX_VECTOR_SHIFT; + + if (ntb->conn_type != NTB_CONN_B2B) { + device_printf(ntb->device, "Connection type %d not supported\n", + ntb->conn_type); + return (ENXIO); + } + + ntb->reg = &xeon_reg; + ntb->self_reg = &xeon_pri_reg; + ntb->peer_reg = &xeon_b2b_reg; + ntb->xlat_reg = &xeon_sec_xlat; + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + ntb->force_db = ntb->fake_db = 0; + ntb->msix_mw_idx = (ntb->mw_count + g_ntb_msix_idx) % + ntb->mw_count; + intel_ntb_printf(2, "Setting up MSIX mw idx %d means %u\n", + g_ntb_msix_idx, ntb->msix_mw_idx); + rc = intel_ntb_mw_set_wc_internal(ntb, ntb->msix_mw_idx, + VM_MEMATTR_UNCACHEABLE); + KASSERT(rc == 0, ("shouldn't fail")); + } else if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) { + /* + * There is a Xeon hardware errata related to writes to SDOORBELL or + * B2BDOORBELL in conjunction with inbound access to NTB MMIO space, + * which may hang the system. To workaround this, use a memory + * window to access the interrupt and scratch pad registers on the + * remote system. + */ + ntb->b2b_mw_idx = (ntb->mw_count + g_ntb_mw_idx) % + ntb->mw_count; + intel_ntb_printf(2, "Setting up b2b mw idx %d means %u\n", + g_ntb_mw_idx, ntb->b2b_mw_idx); + rc = intel_ntb_mw_set_wc_internal(ntb, ntb->b2b_mw_idx, + VM_MEMATTR_UNCACHEABLE); + KASSERT(rc == 0, ("shouldn't fail")); + } else if (HAS_FEATURE(ntb, NTB_B2BDOORBELL_BIT14)) + /* + * HW Errata on bit 14 of b2bdoorbell register. Writes will not be + * mirrored to the remote system. Shrink the number of bits by one, + * since bit 14 is the last bit. + * + * On REGS_THRU_MW errata mode, we don't use the b2bdoorbell register + * anyway. Nor for non-B2B connection types. + */ + ntb->db_count = XEON_DB_COUNT - 1; + + ntb->db_valid_mask = (1ull << ntb->db_count) - 1; + + if (ntb->dev_type == NTB_DEV_USD) + rc = xeon_setup_b2b_mw(ntb, &xeon_b2b_dsd_addr, + &xeon_b2b_usd_addr); + else + rc = xeon_setup_b2b_mw(ntb, &xeon_b2b_usd_addr, + &xeon_b2b_dsd_addr); + if (rc != 0) + return (rc); + + /* Enable Bus Master and Memory Space on the secondary side */ + intel_ntb_reg_write(2, XEON_SPCICMD_OFFSET, + PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + + /* + * Mask all doorbell interrupts. + */ + DB_MASK_LOCK(ntb); + ntb->db_mask = ntb->db_valid_mask; + db_iowrite(ntb, ntb->self_reg->db_mask, ntb->db_mask); + DB_MASK_UNLOCK(ntb); + + rc = intel_ntb_init_isr(ntb); + return (rc); +} + +static int +intel_ntb_atom_init_dev(struct ntb_softc *ntb) +{ + int error; + + KASSERT(ntb->conn_type == NTB_CONN_B2B, + ("Unsupported NTB configuration (%d)\n", ntb->conn_type)); + + ntb->spad_count = ATOM_SPAD_COUNT; + ntb->db_count = ATOM_DB_COUNT; + ntb->db_vec_count = ATOM_DB_MSIX_VECTOR_COUNT; + ntb->db_vec_shift = ATOM_DB_MSIX_VECTOR_SHIFT; + ntb->db_valid_mask = (1ull << ntb->db_count) - 1; + + ntb->reg = &atom_reg; + ntb->self_reg = &atom_pri_reg; + ntb->peer_reg = &atom_b2b_reg; + ntb->xlat_reg = &atom_sec_xlat; + + /* + * FIXME - MSI-X bug on early Atom HW, remove once internal issue is + * resolved. Mask transaction layer internal parity errors. + */ + pci_write_config(ntb->device, 0xFC, 0x4, 4); + + configure_atom_secondary_side_bars(ntb); + + /* Enable Bus Master and Memory Space on the secondary side */ + intel_ntb_reg_write(2, ATOM_SPCICMD_OFFSET, + PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + + error = intel_ntb_init_isr(ntb); + if (error != 0) + return (error); + + /* Initiate PCI-E link training */ + intel_ntb_link_enable(ntb->device, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); + + callout_reset(&ntb->heartbeat_timer, 0, atom_link_hb, ntb); + + return (0); +} + +/* XXX: Linux driver doesn't seem to do any of this for Atom. */ +static void +configure_atom_secondary_side_bars(struct ntb_softc *ntb) +{ + + if (ntb->dev_type == NTB_DEV_USD) { + intel_ntb_reg_write(8, ATOM_PBAR2XLAT_OFFSET, + XEON_B2B_BAR2_ADDR64); + intel_ntb_reg_write(8, ATOM_PBAR4XLAT_OFFSET, + XEON_B2B_BAR4_ADDR64); + intel_ntb_reg_write(8, ATOM_MBAR23_OFFSET, XEON_B2B_BAR2_ADDR64); + intel_ntb_reg_write(8, ATOM_MBAR45_OFFSET, XEON_B2B_BAR4_ADDR64); + } else { + intel_ntb_reg_write(8, ATOM_PBAR2XLAT_OFFSET, + XEON_B2B_BAR2_ADDR64); + intel_ntb_reg_write(8, ATOM_PBAR4XLAT_OFFSET, + XEON_B2B_BAR4_ADDR64); + intel_ntb_reg_write(8, ATOM_MBAR23_OFFSET, XEON_B2B_BAR2_ADDR64); + intel_ntb_reg_write(8, ATOM_MBAR45_OFFSET, XEON_B2B_BAR4_ADDR64); + } +} + + +/* + * When working around Xeon SDOORBELL errata by remapping remote registers in a + * MW, limit the B2B MW to half a MW. By sharing a MW, half the shared MW + * remains for use by a higher layer. + * + * Will only be used if working around SDOORBELL errata and the BIOS-configured + * MW size is sufficiently large. + */ +static unsigned int ntb_b2b_mw_share; +SYSCTL_UINT(_hw_ntb, OID_AUTO, b2b_mw_share, CTLFLAG_RDTUN, &ntb_b2b_mw_share, + 0, "If enabled (non-zero), prefer to share half of the B2B peer register " + "MW with higher level consumers. Both sides of the NTB MUST set the same " + "value here."); + +static void +xeon_reset_sbar_size(struct ntb_softc *ntb, enum ntb_bar idx, + enum ntb_bar regbar) +{ + struct ntb_pci_bar_info *bar; + uint8_t bar_sz; + + if (!HAS_FEATURE(ntb, NTB_SPLIT_BAR) && idx >= NTB_B2B_BAR_3) + return; + + bar = &ntb->bar_info[idx]; + bar_sz = pci_read_config(ntb->device, bar->psz_off, 1); + if (idx == regbar) { + if (ntb->b2b_off != 0) + bar_sz--; + else + bar_sz = 0; + } + pci_write_config(ntb->device, bar->ssz_off, bar_sz, 1); + bar_sz = pci_read_config(ntb->device, bar->ssz_off, 1); + (void)bar_sz; +} + +static void +xeon_set_sbar_base_and_limit(struct ntb_softc *ntb, uint64_t bar_addr, + enum ntb_bar idx, enum ntb_bar regbar) +{ + uint64_t reg_val; + uint32_t base_reg, lmt_reg; + + bar_get_xlat_params(ntb, idx, &base_reg, NULL, &lmt_reg); + if (idx == regbar) { + if (ntb->b2b_off) + bar_addr += ntb->b2b_off; + else + bar_addr = 0; + } + + if (!bar_is_64bit(ntb, idx)) { + intel_ntb_reg_write(4, base_reg, bar_addr); + reg_val = intel_ntb_reg_read(4, base_reg); + (void)reg_val; + + intel_ntb_reg_write(4, lmt_reg, bar_addr); + reg_val = intel_ntb_reg_read(4, lmt_reg); + (void)reg_val; + } else { + intel_ntb_reg_write(8, base_reg, bar_addr); + reg_val = intel_ntb_reg_read(8, base_reg); + (void)reg_val; + + intel_ntb_reg_write(8, lmt_reg, bar_addr); + reg_val = intel_ntb_reg_read(8, lmt_reg); + (void)reg_val; + } +} + +static void +xeon_set_pbar_xlat(struct ntb_softc *ntb, uint64_t base_addr, enum ntb_bar idx) +{ + struct ntb_pci_bar_info *bar; + + bar = &ntb->bar_info[idx]; + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR) && idx >= NTB_B2B_BAR_2) { + intel_ntb_reg_write(4, bar->pbarxlat_off, base_addr); + base_addr = intel_ntb_reg_read(4, bar->pbarxlat_off); + } else { + intel_ntb_reg_write(8, bar->pbarxlat_off, base_addr); + base_addr = intel_ntb_reg_read(8, bar->pbarxlat_off); + } + (void)base_addr; +} + +static int +xeon_setup_b2b_mw(struct ntb_softc *ntb, const struct ntb_b2b_addr *addr, + const struct ntb_b2b_addr *peer_addr) +{ + struct ntb_pci_bar_info *b2b_bar; + vm_size_t bar_size; + uint64_t bar_addr; + enum ntb_bar b2b_bar_num, i; + + if (ntb->b2b_mw_idx == B2B_MW_DISABLED) { + b2b_bar = NULL; + b2b_bar_num = NTB_CONFIG_BAR; + ntb->b2b_off = 0; + } else { + b2b_bar_num = intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx); + KASSERT(b2b_bar_num > 0 && b2b_bar_num < NTB_MAX_BARS, + ("invalid b2b mw bar")); + + b2b_bar = &ntb->bar_info[b2b_bar_num]; + bar_size = b2b_bar->size; + + if (ntb_b2b_mw_share != 0 && + (bar_size >> 1) >= XEON_B2B_MIN_SIZE) + ntb->b2b_off = bar_size >> 1; + else if (bar_size >= XEON_B2B_MIN_SIZE) { + ntb->b2b_off = 0; + } else { + device_printf(ntb->device, + "B2B bar size is too small!\n"); + return (EIO); + } + } + + /* + * Reset the secondary bar sizes to match the primary bar sizes. + * (Except, disable or halve the size of the B2B secondary bar.) + */ + for (i = NTB_B2B_BAR_1; i < NTB_MAX_BARS; i++) + xeon_reset_sbar_size(ntb, i, b2b_bar_num); + + bar_addr = 0; + if (b2b_bar_num == NTB_CONFIG_BAR) + bar_addr = addr->bar0_addr; + else if (b2b_bar_num == NTB_B2B_BAR_1) + bar_addr = addr->bar2_addr64; + else if (b2b_bar_num == NTB_B2B_BAR_2 && !HAS_FEATURE(ntb, NTB_SPLIT_BAR)) + bar_addr = addr->bar4_addr64; + else if (b2b_bar_num == NTB_B2B_BAR_2) + bar_addr = addr->bar4_addr32; + else if (b2b_bar_num == NTB_B2B_BAR_3) + bar_addr = addr->bar5_addr32; + else + KASSERT(false, ("invalid bar")); + + intel_ntb_reg_write(8, XEON_SBAR0BASE_OFFSET, bar_addr); + + /* + * Other SBARs are normally hit by the PBAR xlat, except for the b2b + * register BAR. The B2B BAR is either disabled above or configured + * half-size. It starts at PBAR xlat + offset. + * + * Also set up incoming BAR limits == base (zero length window). + */ + xeon_set_sbar_base_and_limit(ntb, addr->bar2_addr64, NTB_B2B_BAR_1, + b2b_bar_num); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + xeon_set_sbar_base_and_limit(ntb, addr->bar4_addr32, + NTB_B2B_BAR_2, b2b_bar_num); + xeon_set_sbar_base_and_limit(ntb, addr->bar5_addr32, + NTB_B2B_BAR_3, b2b_bar_num); + } else + xeon_set_sbar_base_and_limit(ntb, addr->bar4_addr64, + NTB_B2B_BAR_2, b2b_bar_num); + + /* Zero incoming translation addrs */ + intel_ntb_reg_write(8, XEON_SBAR2XLAT_OFFSET, 0); + intel_ntb_reg_write(8, XEON_SBAR4XLAT_OFFSET, 0); + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + uint32_t xlat_reg, lmt_reg; + enum ntb_bar bar_num; + + /* + * We point the chosen MSIX MW BAR xlat to remote LAPIC for + * workaround + */ + bar_num = intel_ntb_mw_to_bar(ntb, ntb->msix_mw_idx); + bar_get_xlat_params(ntb, bar_num, NULL, &xlat_reg, &lmt_reg); + if (bar_is_64bit(ntb, bar_num)) { + intel_ntb_reg_write(8, xlat_reg, MSI_INTEL_ADDR_BASE); + ntb->msix_xlat = intel_ntb_reg_read(8, xlat_reg); + intel_ntb_reg_write(8, lmt_reg, 0); + } else { + intel_ntb_reg_write(4, xlat_reg, MSI_INTEL_ADDR_BASE); + ntb->msix_xlat = intel_ntb_reg_read(4, xlat_reg); + intel_ntb_reg_write(4, lmt_reg, 0); + } + + ntb->peer_lapic_bar = &ntb->bar_info[bar_num]; + } + (void)intel_ntb_reg_read(8, XEON_SBAR2XLAT_OFFSET); + (void)intel_ntb_reg_read(8, XEON_SBAR4XLAT_OFFSET); + + /* Zero outgoing translation limits (whole bar size windows) */ + intel_ntb_reg_write(8, XEON_PBAR2LMT_OFFSET, 0); + intel_ntb_reg_write(8, XEON_PBAR4LMT_OFFSET, 0); + + /* Set outgoing translation offsets */ + xeon_set_pbar_xlat(ntb, peer_addr->bar2_addr64, NTB_B2B_BAR_1); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + xeon_set_pbar_xlat(ntb, peer_addr->bar4_addr32, NTB_B2B_BAR_2); + xeon_set_pbar_xlat(ntb, peer_addr->bar5_addr32, NTB_B2B_BAR_3); + } else + xeon_set_pbar_xlat(ntb, peer_addr->bar4_addr64, NTB_B2B_BAR_2); + + /* Set the translation offset for B2B registers */ + bar_addr = 0; + if (b2b_bar_num == NTB_CONFIG_BAR) + bar_addr = peer_addr->bar0_addr; + else if (b2b_bar_num == NTB_B2B_BAR_1) + bar_addr = peer_addr->bar2_addr64; + else if (b2b_bar_num == NTB_B2B_BAR_2 && !HAS_FEATURE(ntb, NTB_SPLIT_BAR)) + bar_addr = peer_addr->bar4_addr64; + else if (b2b_bar_num == NTB_B2B_BAR_2) + bar_addr = peer_addr->bar4_addr32; + else if (b2b_bar_num == NTB_B2B_BAR_3) + bar_addr = peer_addr->bar5_addr32; + else + KASSERT(false, ("invalid bar")); + + /* + * B2B_XLAT_OFFSET is a 64-bit register but can only be written 32 bits + * at a time. + */ + intel_ntb_reg_write(4, XEON_B2B_XLAT_OFFSETL, bar_addr & 0xffffffff); + intel_ntb_reg_write(4, XEON_B2B_XLAT_OFFSETU, bar_addr >> 32); + return (0); +} + +static inline bool +_xeon_link_is_up(struct ntb_softc *ntb) +{ + + if (ntb->conn_type == NTB_CONN_TRANSPARENT) + return (true); + return ((ntb->lnk_sta & NTB_LINK_STATUS_ACTIVE) != 0); +} + +static inline bool +link_is_up(struct ntb_softc *ntb) +{ + + if (ntb->type == NTB_XEON) + return (_xeon_link_is_up(ntb) && (ntb->peer_msix_good || + !HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP))); + + KASSERT(ntb->type == NTB_ATOM, ("ntb type")); + return ((ntb->ntb_ctl & ATOM_CNTL_LINK_DOWN) == 0); +} + +static inline bool +atom_link_is_err(struct ntb_softc *ntb) +{ + uint32_t status; + + KASSERT(ntb->type == NTB_ATOM, ("ntb type")); + + status = intel_ntb_reg_read(4, ATOM_LTSSMSTATEJMP_OFFSET); + if ((status & ATOM_LTSSMSTATEJMP_FORCEDETECT) != 0) + return (true); + + status = intel_ntb_reg_read(4, ATOM_IBSTERRRCRVSTS0_OFFSET); + return ((status & ATOM_IBIST_ERR_OFLOW) != 0); +} + +/* Atom does not have link status interrupt, poll on that platform */ +static void +atom_link_hb(void *arg) +{ + struct ntb_softc *ntb = arg; + sbintime_t timo, poll_ts; + + timo = NTB_HB_TIMEOUT * hz; + poll_ts = ntb->last_ts + timo; + + /* + * Delay polling the link status if an interrupt was received, unless + * the cached link status says the link is down. + */ + if ((sbintime_t)ticks - poll_ts < 0 && link_is_up(ntb)) { + timo = poll_ts - ticks; + goto out; + } + + if (intel_ntb_poll_link(ntb)) + ntb_link_event(ntb->device); + + if (!link_is_up(ntb) && atom_link_is_err(ntb)) { + /* Link is down with error, proceed with recovery */ + callout_reset(&ntb->lr_timer, 0, recover_atom_link, ntb); + return; + } + +out: + callout_reset(&ntb->heartbeat_timer, timo, atom_link_hb, ntb); +} + +static void +atom_perform_link_restart(struct ntb_softc *ntb) +{ + uint32_t status; + + /* Driver resets the NTB ModPhy lanes - magic! */ + intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG6, 0xe0); + intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG4, 0x40); + intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG4, 0x60); + intel_ntb_reg_write(1, ATOM_MODPHY_PCSREG6, 0x60); + + /* Driver waits 100ms to allow the NTB ModPhy to settle */ + pause("ModPhy", hz / 10); + + /* Clear AER Errors, write to clear */ + status = intel_ntb_reg_read(4, ATOM_ERRCORSTS_OFFSET); + status &= PCIM_AER_COR_REPLAY_ROLLOVER; + intel_ntb_reg_write(4, ATOM_ERRCORSTS_OFFSET, status); + + /* Clear unexpected electrical idle event in LTSSM, write to clear */ + status = intel_ntb_reg_read(4, ATOM_LTSSMERRSTS0_OFFSET); + status |= ATOM_LTSSMERRSTS0_UNEXPECTEDEI; + intel_ntb_reg_write(4, ATOM_LTSSMERRSTS0_OFFSET, status); + + /* Clear DeSkew Buffer error, write to clear */ + status = intel_ntb_reg_read(4, ATOM_DESKEWSTS_OFFSET); + status |= ATOM_DESKEWSTS_DBERR; + intel_ntb_reg_write(4, ATOM_DESKEWSTS_OFFSET, status); + + status = intel_ntb_reg_read(4, ATOM_IBSTERRRCRVSTS0_OFFSET); + status &= ATOM_IBIST_ERR_OFLOW; + intel_ntb_reg_write(4, ATOM_IBSTERRRCRVSTS0_OFFSET, status); + + /* Releases the NTB state machine to allow the link to retrain */ + status = intel_ntb_reg_read(4, ATOM_LTSSMSTATEJMP_OFFSET); + status &= ~ATOM_LTSSMSTATEJMP_FORCEDETECT; + intel_ntb_reg_write(4, ATOM_LTSSMSTATEJMP_OFFSET, status); +} + +static int +intel_ntb_link_enable(device_t dev, enum ntb_speed speed __unused, + enum ntb_width width __unused) +{ + struct ntb_softc *ntb = device_get_softc(dev); + uint32_t cntl; + + intel_ntb_printf(2, "%s\n", __func__); + + if (ntb->type == NTB_ATOM) { + pci_write_config(ntb->device, NTB_PPD_OFFSET, + ntb->ppd | ATOM_PPD_INIT_LINK, 4); + return (0); + } + + if (ntb->conn_type == NTB_CONN_TRANSPARENT) { + ntb_link_event(dev); + return (0); + } + + cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); + cntl &= ~(NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK); + cntl |= NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP; + cntl |= NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP; + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) + cntl |= NTB_CNTL_P2S_BAR5_SNOOP | NTB_CNTL_S2P_BAR5_SNOOP; + intel_ntb_reg_write(4, ntb->reg->ntb_ctl, cntl); + return (0); +} + +static int +intel_ntb_link_disable(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + uint32_t cntl; + + intel_ntb_printf(2, "%s\n", __func__); + + if (ntb->conn_type == NTB_CONN_TRANSPARENT) { + ntb_link_event(dev); + return (0); + } + + cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); + cntl &= ~(NTB_CNTL_P2S_BAR23_SNOOP | NTB_CNTL_S2P_BAR23_SNOOP); + cntl &= ~(NTB_CNTL_P2S_BAR4_SNOOP | NTB_CNTL_S2P_BAR4_SNOOP); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) + cntl &= ~(NTB_CNTL_P2S_BAR5_SNOOP | NTB_CNTL_S2P_BAR5_SNOOP); + cntl |= NTB_CNTL_LINK_DISABLE | NTB_CNTL_CFG_LOCK; + intel_ntb_reg_write(4, ntb->reg->ntb_ctl, cntl); + return (0); +} + +static bool +intel_ntb_link_enabled(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + uint32_t cntl; + + if (ntb->type == NTB_ATOM) { + cntl = pci_read_config(ntb->device, NTB_PPD_OFFSET, 4); + return ((cntl & ATOM_PPD_INIT_LINK) != 0); + } + + if (ntb->conn_type == NTB_CONN_TRANSPARENT) + return (true); + + cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); + return ((cntl & NTB_CNTL_LINK_DISABLE) == 0); +} + +static void +recover_atom_link(void *arg) +{ + struct ntb_softc *ntb = arg; + unsigned speed, width, oldspeed, oldwidth; + uint32_t status32; + + atom_perform_link_restart(ntb); + + /* + * There is a potential race between the 2 NTB devices recovering at + * the same time. If the times are the same, the link will not recover + * and the driver will be stuck in this loop forever. Add a random + * interval to the recovery time to prevent this race. + */ + status32 = arc4random() % ATOM_LINK_RECOVERY_TIME; + pause("Link", (ATOM_LINK_RECOVERY_TIME + status32) * hz / 1000); + + if (atom_link_is_err(ntb)) + goto retry; + + status32 = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); + if ((status32 & ATOM_CNTL_LINK_DOWN) != 0) + goto out; + + status32 = intel_ntb_reg_read(4, ntb->reg->lnk_sta); + width = NTB_LNK_STA_WIDTH(status32); + speed = status32 & NTB_LINK_SPEED_MASK; + + oldwidth = NTB_LNK_STA_WIDTH(ntb->lnk_sta); + oldspeed = ntb->lnk_sta & NTB_LINK_SPEED_MASK; + if (oldwidth != width || oldspeed != speed) + goto retry; + +out: + callout_reset(&ntb->heartbeat_timer, NTB_HB_TIMEOUT * hz, atom_link_hb, + ntb); + return; + +retry: + callout_reset(&ntb->lr_timer, NTB_HB_TIMEOUT * hz, recover_atom_link, + ntb); +} + +/* + * Polls the HW link status register(s); returns true if something has changed. + */ +static bool +intel_ntb_poll_link(struct ntb_softc *ntb) +{ + uint32_t ntb_cntl; + uint16_t reg_val; + + if (ntb->type == NTB_ATOM) { + ntb_cntl = intel_ntb_reg_read(4, ntb->reg->ntb_ctl); + if (ntb_cntl == ntb->ntb_ctl) + return (false); + + ntb->ntb_ctl = ntb_cntl; + ntb->lnk_sta = intel_ntb_reg_read(4, ntb->reg->lnk_sta); + } else { + db_iowrite_raw(ntb, ntb->self_reg->db_bell, ntb->db_link_mask); + + reg_val = pci_read_config(ntb->device, ntb->reg->lnk_sta, 2); + if (reg_val == ntb->lnk_sta) + return (false); + + ntb->lnk_sta = reg_val; + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + if (_xeon_link_is_up(ntb)) { + if (!ntb->peer_msix_good) { + callout_reset(&ntb->peer_msix_work, 0, + intel_ntb_exchange_msix, ntb); + return (false); + } + } else { + ntb->peer_msix_good = false; + ntb->peer_msix_done = false; + } + } + } + return (true); +} + +static inline enum ntb_speed +intel_ntb_link_sta_speed(struct ntb_softc *ntb) +{ + + if (!link_is_up(ntb)) + return (NTB_SPEED_NONE); + return (ntb->lnk_sta & NTB_LINK_SPEED_MASK); +} + +static inline enum ntb_width +intel_ntb_link_sta_width(struct ntb_softc *ntb) +{ + + if (!link_is_up(ntb)) + return (NTB_WIDTH_NONE); + return (NTB_LNK_STA_WIDTH(ntb->lnk_sta)); +} + +SYSCTL_NODE(_hw_ntb, OID_AUTO, debug_info, CTLFLAG_RW, 0, + "Driver state, statistics, and HW registers"); + +#define NTB_REGSZ_MASK (3ul << 30) +#define NTB_REG_64 (1ul << 30) +#define NTB_REG_32 (2ul << 30) +#define NTB_REG_16 (3ul << 30) +#define NTB_REG_8 (0ul << 30) + +#define NTB_DB_READ (1ul << 29) +#define NTB_PCI_REG (1ul << 28) +#define NTB_REGFLAGS_MASK (NTB_REGSZ_MASK | NTB_DB_READ | NTB_PCI_REG) + +static void +intel_ntb_sysctl_init(struct ntb_softc *ntb) +{ + struct sysctl_oid_list *globals, *tree_par, *regpar, *statpar, *errpar; + struct sysctl_ctx_list *ctx; + struct sysctl_oid *tree, *tmptree; + + ctx = device_get_sysctl_ctx(ntb->device); + globals = SYSCTL_CHILDREN(device_get_sysctl_tree(ntb->device)); + + SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "link_status", + CTLFLAG_RD | CTLTYPE_STRING, ntb, 0, + sysctl_handle_link_status_human, "A", + "Link status (human readable)"); + SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "active", + CTLFLAG_RD | CTLTYPE_UINT, ntb, 0, sysctl_handle_link_status, + "IU", "Link status (1=active, 0=inactive)"); + SYSCTL_ADD_PROC(ctx, globals, OID_AUTO, "admin_up", + CTLFLAG_RW | CTLTYPE_UINT, ntb, 0, sysctl_handle_link_admin, + "IU", "Set/get interface status (1=UP, 0=DOWN)"); + + tree = SYSCTL_ADD_NODE(ctx, globals, OID_AUTO, "debug_info", + CTLFLAG_RD, NULL, "Driver state, statistics, and HW registers"); + tree_par = SYSCTL_CHILDREN(tree); + + SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "conn_type", CTLFLAG_RD, + &ntb->conn_type, 0, "0 - Transparent; 1 - B2B; 2 - Root Port"); + SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "dev_type", CTLFLAG_RD, + &ntb->dev_type, 0, "0 - USD; 1 - DSD"); + SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "ppd", CTLFLAG_RD, + &ntb->ppd, 0, "Raw PPD register (cached)"); + + if (ntb->b2b_mw_idx != B2B_MW_DISABLED) { + SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "b2b_idx", CTLFLAG_RD, + &ntb->b2b_mw_idx, 0, + "Index of the MW used for B2B remote register access"); + SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "b2b_off", + CTLFLAG_RD, &ntb->b2b_off, + "If non-zero, offset of B2B register region in shared MW"); + } + + SYSCTL_ADD_PROC(ctx, tree_par, OID_AUTO, "features", + CTLFLAG_RD | CTLTYPE_STRING, ntb, 0, sysctl_handle_features, "A", + "Features/errata of this NTB device"); + + SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "ntb_ctl", CTLFLAG_RD, + __DEVOLATILE(uint32_t *, &ntb->ntb_ctl), 0, + "NTB CTL register (cached)"); + SYSCTL_ADD_UINT(ctx, tree_par, OID_AUTO, "lnk_sta", CTLFLAG_RD, + __DEVOLATILE(uint32_t *, &ntb->lnk_sta), 0, + "LNK STA register (cached)"); + + SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "mw_count", CTLFLAG_RD, + &ntb->mw_count, 0, "MW count"); + SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "spad_count", CTLFLAG_RD, + &ntb->spad_count, 0, "Scratchpad count"); + SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "db_count", CTLFLAG_RD, + &ntb->db_count, 0, "Doorbell count"); + SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "db_vec_count", CTLFLAG_RD, + &ntb->db_vec_count, 0, "Doorbell vector count"); + SYSCTL_ADD_U8(ctx, tree_par, OID_AUTO, "db_vec_shift", CTLFLAG_RD, + &ntb->db_vec_shift, 0, "Doorbell vector shift"); + + SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "db_valid_mask", CTLFLAG_RD, + &ntb->db_valid_mask, "Doorbell valid mask"); + SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "db_link_mask", CTLFLAG_RD, + &ntb->db_link_mask, "Doorbell link mask"); + SYSCTL_ADD_UQUAD(ctx, tree_par, OID_AUTO, "db_mask", CTLFLAG_RD, + &ntb->db_mask, "Doorbell mask (cached)"); + + tmptree = SYSCTL_ADD_NODE(ctx, tree_par, OID_AUTO, "registers", + CTLFLAG_RD, NULL, "Raw HW registers (big-endian)"); + regpar = SYSCTL_CHILDREN(tmptree); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "ntbcntl", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, NTB_REG_32 | + ntb->reg->ntb_ctl, sysctl_handle_register, "IU", + "NTB Control register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "lnkcap", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, NTB_REG_32 | + 0x19c, sysctl_handle_register, "IU", + "NTB Link Capabilities"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "lnkcon", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, NTB_REG_32 | + 0x1a0, sysctl_handle_register, "IU", + "NTB Link Control register"); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "db_mask", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | NTB_DB_READ | ntb->self_reg->db_mask, + sysctl_handle_register, "QU", "Doorbell mask register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "db_bell", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | NTB_DB_READ | ntb->self_reg->db_bell, + sysctl_handle_register, "QU", "Doorbell register"); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat23", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar2_xlat, + sysctl_handle_register, "QU", "Incoming XLAT23 register"); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat4", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->xlat_reg->bar4_xlat, + sysctl_handle_register, "IU", "Incoming XLAT4 register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat5", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->xlat_reg->bar5_xlat, + sysctl_handle_register, "IU", "Incoming XLAT5 register"); + } else { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_xlat45", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar4_xlat, + sysctl_handle_register, "QU", "Incoming XLAT45 register"); + } + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt23", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar2_limit, + sysctl_handle_register, "QU", "Incoming LMT23 register"); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt4", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->xlat_reg->bar4_limit, + sysctl_handle_register, "IU", "Incoming LMT4 register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt5", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->xlat_reg->bar5_limit, + sysctl_handle_register, "IU", "Incoming LMT5 register"); + } else { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "incoming_lmt45", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar4_limit, + sysctl_handle_register, "QU", "Incoming LMT45 register"); + } + + if (ntb->type == NTB_ATOM) + return; + + tmptree = SYSCTL_ADD_NODE(ctx, regpar, OID_AUTO, "xeon_stats", + CTLFLAG_RD, NULL, "Xeon HW statistics"); + statpar = SYSCTL_CHILDREN(tmptree); + SYSCTL_ADD_PROC(ctx, statpar, OID_AUTO, "upstream_mem_miss", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_16 | XEON_USMEMMISS_OFFSET, + sysctl_handle_register, "SU", "Upstream Memory Miss"); + + tmptree = SYSCTL_ADD_NODE(ctx, regpar, OID_AUTO, "xeon_hw_err", + CTLFLAG_RD, NULL, "Xeon HW errors"); + errpar = SYSCTL_CHILDREN(tmptree); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "ppd", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | NTB_PPD_OFFSET, + sysctl_handle_register, "CU", "PPD"); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "pbar23_sz", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | XEON_PBAR23SZ_OFFSET, + sysctl_handle_register, "CU", "PBAR23 SZ (log2)"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "pbar4_sz", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | XEON_PBAR4SZ_OFFSET, + sysctl_handle_register, "CU", "PBAR4 SZ (log2)"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "pbar5_sz", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | XEON_PBAR5SZ_OFFSET, + sysctl_handle_register, "CU", "PBAR5 SZ (log2)"); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar23_sz", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | XEON_SBAR23SZ_OFFSET, + sysctl_handle_register, "CU", "SBAR23 SZ (log2)"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar4_sz", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | XEON_SBAR4SZ_OFFSET, + sysctl_handle_register, "CU", "SBAR4 SZ (log2)"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar5_sz", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_8 | NTB_PCI_REG | XEON_SBAR5SZ_OFFSET, + sysctl_handle_register, "CU", "SBAR5 SZ (log2)"); + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "devsts", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_16 | NTB_PCI_REG | XEON_DEVSTS_OFFSET, + sysctl_handle_register, "SU", "DEVSTS"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "lnksts", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_16 | NTB_PCI_REG | XEON_LINK_STATUS_OFFSET, + sysctl_handle_register, "SU", "LNKSTS"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "slnksts", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_16 | NTB_PCI_REG | XEON_SLINK_STATUS_OFFSET, + sysctl_handle_register, "SU", "SLNKSTS"); + + SYSCTL_ADD_PROC(ctx, errpar, OID_AUTO, "uncerrsts", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | NTB_PCI_REG | XEON_UNCERRSTS_OFFSET, + sysctl_handle_register, "IU", "UNCERRSTS"); + SYSCTL_ADD_PROC(ctx, errpar, OID_AUTO, "corerrsts", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | NTB_PCI_REG | XEON_CORERRSTS_OFFSET, + sysctl_handle_register, "IU", "CORERRSTS"); + + if (ntb->conn_type != NTB_CONN_B2B) + return; + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat23", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->bar_info[NTB_B2B_BAR_1].pbarxlat_off, + sysctl_handle_register, "QU", "Outgoing XLAT23 register"); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat4", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->bar_info[NTB_B2B_BAR_2].pbarxlat_off, + sysctl_handle_register, "IU", "Outgoing XLAT4 register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat5", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->bar_info[NTB_B2B_BAR_3].pbarxlat_off, + sysctl_handle_register, "IU", "Outgoing XLAT5 register"); + } else { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_xlat45", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->bar_info[NTB_B2B_BAR_2].pbarxlat_off, + sysctl_handle_register, "QU", "Outgoing XLAT45 register"); + } + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt23", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | XEON_PBAR2LMT_OFFSET, + sysctl_handle_register, "QU", "Outgoing LMT23 register"); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt4", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | XEON_PBAR4LMT_OFFSET, + sysctl_handle_register, "IU", "Outgoing LMT4 register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt5", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | XEON_PBAR5LMT_OFFSET, + sysctl_handle_register, "IU", "Outgoing LMT5 register"); + } else { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "outgoing_lmt45", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | XEON_PBAR4LMT_OFFSET, + sysctl_handle_register, "QU", "Outgoing LMT45 register"); + } + + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar01_base", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar0_base, + sysctl_handle_register, "QU", "Secondary BAR01 base register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar23_base", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar2_base, + sysctl_handle_register, "QU", "Secondary BAR23 base register"); + if (HAS_FEATURE(ntb, NTB_SPLIT_BAR)) { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar4_base", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->xlat_reg->bar4_base, + sysctl_handle_register, "IU", + "Secondary BAR4 base register"); + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar5_base", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_32 | ntb->xlat_reg->bar5_base, + sysctl_handle_register, "IU", + "Secondary BAR5 base register"); + } else { + SYSCTL_ADD_PROC(ctx, regpar, OID_AUTO, "sbar45_base", + CTLFLAG_RD | CTLTYPE_OPAQUE, ntb, + NTB_REG_64 | ntb->xlat_reg->bar4_base, + sysctl_handle_register, "QU", + "Secondary BAR45 base register"); + } +} + +static int +sysctl_handle_features(SYSCTL_HANDLER_ARGS) +{ + struct ntb_softc *ntb = arg1; + struct sbuf sb; + int error; + + sbuf_new_for_sysctl(&sb, NULL, 256, req); + + sbuf_printf(&sb, "%b", ntb->features, NTB_FEATURES_STR); + error = sbuf_finish(&sb); + sbuf_delete(&sb); + + if (error || !req->newptr) + return (error); + return (EINVAL); +} + +static int +sysctl_handle_link_admin(SYSCTL_HANDLER_ARGS) +{ + struct ntb_softc *ntb = arg1; + unsigned old, new; + int error; + + old = intel_ntb_link_enabled(ntb->device); + + error = SYSCTL_OUT(req, &old, sizeof(old)); + if (error != 0 || req->newptr == NULL) + return (error); + + error = SYSCTL_IN(req, &new, sizeof(new)); + if (error != 0) + return (error); + + intel_ntb_printf(0, "Admin set interface state to '%sabled'\n", + (new != 0)? "en" : "dis"); + + if (new != 0) + error = intel_ntb_link_enable(ntb->device, NTB_SPEED_AUTO, NTB_WIDTH_AUTO); + else + error = intel_ntb_link_disable(ntb->device); + return (error); +} + +static int +sysctl_handle_link_status_human(SYSCTL_HANDLER_ARGS) +{ + struct ntb_softc *ntb = arg1; + struct sbuf sb; + enum ntb_speed speed; + enum ntb_width width; + int error; + + sbuf_new_for_sysctl(&sb, NULL, 32, req); + + if (intel_ntb_link_is_up(ntb->device, &speed, &width)) + sbuf_printf(&sb, "up / PCIe Gen %u / Width x%u", + (unsigned)speed, (unsigned)width); + else + sbuf_printf(&sb, "down"); + + error = sbuf_finish(&sb); + sbuf_delete(&sb); + + if (error || !req->newptr) + return (error); + return (EINVAL); +} + +static int +sysctl_handle_link_status(SYSCTL_HANDLER_ARGS) +{ + struct ntb_softc *ntb = arg1; + unsigned res; + int error; + + res = intel_ntb_link_is_up(ntb->device, NULL, NULL); + + error = SYSCTL_OUT(req, &res, sizeof(res)); + if (error || !req->newptr) + return (error); + return (EINVAL); +} + +static int +sysctl_handle_register(SYSCTL_HANDLER_ARGS) +{ + struct ntb_softc *ntb; + const void *outp; + uintptr_t sz; + uint64_t umv; + char be[sizeof(umv)]; + size_t outsz; + uint32_t reg; + bool db, pci; + int error; + + ntb = arg1; + reg = arg2 & ~NTB_REGFLAGS_MASK; + sz = arg2 & NTB_REGSZ_MASK; + db = (arg2 & NTB_DB_READ) != 0; + pci = (arg2 & NTB_PCI_REG) != 0; + + KASSERT(!(db && pci), ("bogus")); + + if (db) { + KASSERT(sz == NTB_REG_64, ("bogus")); + umv = db_ioread(ntb, reg); + outsz = sizeof(uint64_t); + } else { + switch (sz) { + case NTB_REG_64: + if (pci) + umv = pci_read_config(ntb->device, reg, 8); + else + umv = intel_ntb_reg_read(8, reg); + outsz = sizeof(uint64_t); + break; + case NTB_REG_32: + if (pci) + umv = pci_read_config(ntb->device, reg, 4); + else + umv = intel_ntb_reg_read(4, reg); + outsz = sizeof(uint32_t); + break; + case NTB_REG_16: + if (pci) + umv = pci_read_config(ntb->device, reg, 2); + else + umv = intel_ntb_reg_read(2, reg); + outsz = sizeof(uint16_t); + break; + case NTB_REG_8: + if (pci) + umv = pci_read_config(ntb->device, reg, 1); + else + umv = intel_ntb_reg_read(1, reg); + outsz = sizeof(uint8_t); + break; + default: + panic("bogus"); + break; + } + } + + /* Encode bigendian so that sysctl -x is legible. */ + be64enc(be, umv); + outp = ((char *)be) + sizeof(umv) - outsz; + + error = SYSCTL_OUT(req, outp, outsz); + if (error || !req->newptr) + return (error); + return (EINVAL); +} + +static unsigned +intel_ntb_user_mw_to_idx(struct ntb_softc *ntb, unsigned uidx) +{ + + if ((ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && + uidx >= ntb->b2b_mw_idx) || + (ntb->msix_mw_idx != B2B_MW_DISABLED && uidx >= ntb->msix_mw_idx)) + uidx++; + if ((ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0 && + uidx >= ntb->b2b_mw_idx) && + (ntb->msix_mw_idx != B2B_MW_DISABLED && uidx >= ntb->msix_mw_idx)) + uidx++; + return (uidx); +} + +#ifndef EARLY_AP_STARTUP +static int msix_ready; + +static void +intel_ntb_msix_ready(void *arg __unused) +{ + + msix_ready = 1; +} +SYSINIT(intel_ntb_msix_ready, SI_SUB_SMP, SI_ORDER_ANY, + intel_ntb_msix_ready, NULL); +#endif + +static void +intel_ntb_exchange_msix(void *ctx) +{ + struct ntb_softc *ntb; + uint32_t val; + unsigned i; + + ntb = ctx; + + if (ntb->peer_msix_good) + goto msix_good; + if (ntb->peer_msix_done) + goto msix_done; + +#ifndef EARLY_AP_STARTUP + /* Block MSIX negotiation until SMP started and IRQ reshuffled. */ + if (!msix_ready) + goto reschedule; +#endif + + intel_ntb_get_msix_info(ntb); + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_DATA0 + i, + ntb->msix_data[i].nmd_data); + intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_OFS0 + i, + ntb->msix_data[i].nmd_ofs - ntb->msix_xlat); + } + intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_GUARD, NTB_MSIX_VER_GUARD); + + intel_ntb_spad_read(ntb->device, NTB_MSIX_GUARD, &val); + if (val != NTB_MSIX_VER_GUARD) + goto reschedule; + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + intel_ntb_spad_read(ntb->device, NTB_MSIX_DATA0 + i, &val); + intel_ntb_printf(2, "remote MSIX data(%u): 0x%x\n", i, val); + ntb->peer_msix_data[i].nmd_data = val; + intel_ntb_spad_read(ntb->device, NTB_MSIX_OFS0 + i, &val); + intel_ntb_printf(2, "remote MSIX addr(%u): 0x%x\n", i, val); + ntb->peer_msix_data[i].nmd_ofs = val; + } + + ntb->peer_msix_done = true; + +msix_done: + intel_ntb_peer_spad_write(ntb->device, NTB_MSIX_DONE, NTB_MSIX_RECEIVED); + intel_ntb_spad_read(ntb->device, NTB_MSIX_DONE, &val); + if (val != NTB_MSIX_RECEIVED) + goto reschedule; + + intel_ntb_spad_clear(ntb->device); + ntb->peer_msix_good = true; + /* Give peer time to see our NTB_MSIX_RECEIVED. */ + goto reschedule; + +msix_good: + intel_ntb_poll_link(ntb); + ntb_link_event(ntb->device); + return; + +reschedule: + ntb->lnk_sta = pci_read_config(ntb->device, ntb->reg->lnk_sta, 2); + if (_xeon_link_is_up(ntb)) { + callout_reset(&ntb->peer_msix_work, + hz * (ntb->peer_msix_good ? 2 : 1) / 100, + intel_ntb_exchange_msix, ntb); + } else + intel_ntb_spad_clear(ntb->device); +} + +/* + * Public API to the rest of the OS + */ + +static uint8_t +intel_ntb_spad_count(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + return (ntb->spad_count); +} + +static uint8_t +intel_ntb_mw_count(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + uint8_t res; + + res = ntb->mw_count; + if (ntb->b2b_mw_idx != B2B_MW_DISABLED && ntb->b2b_off == 0) + res--; + if (ntb->msix_mw_idx != B2B_MW_DISABLED) + res--; + return (res); +} + +static int +intel_ntb_spad_write(device_t dev, unsigned int idx, uint32_t val) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (idx >= ntb->spad_count) + return (EINVAL); + + intel_ntb_reg_write(4, ntb->self_reg->spad + idx * 4, val); + + return (0); +} + +/* + * Zeros the local scratchpad. + */ +static void +intel_ntb_spad_clear(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + unsigned i; + + for (i = 0; i < ntb->spad_count; i++) + intel_ntb_spad_write(dev, i, 0); +} + +static int +intel_ntb_spad_read(device_t dev, unsigned int idx, uint32_t *val) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (idx >= ntb->spad_count) + return (EINVAL); + + *val = intel_ntb_reg_read(4, ntb->self_reg->spad + idx * 4); + + return (0); +} + +static int +intel_ntb_peer_spad_write(device_t dev, unsigned int idx, uint32_t val) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (idx >= ntb->spad_count) + return (EINVAL); + + if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) + intel_ntb_mw_write(4, XEON_SPAD_OFFSET + idx * 4, val); + else + intel_ntb_reg_write(4, ntb->peer_reg->spad + idx * 4, val); + + return (0); +} + +static int +intel_ntb_peer_spad_read(device_t dev, unsigned int idx, uint32_t *val) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (idx >= ntb->spad_count) + return (EINVAL); + + if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) + *val = intel_ntb_mw_read(4, XEON_SPAD_OFFSET + idx * 4); + else + *val = intel_ntb_reg_read(4, ntb->peer_reg->spad + idx * 4); + + return (0); +} + +static int +intel_ntb_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base, + caddr_t *vbase, size_t *size, size_t *align, size_t *align_size, + bus_addr_t *plimit) +{ + struct ntb_softc *ntb = device_get_softc(dev); + struct ntb_pci_bar_info *bar; + bus_addr_t limit; + size_t bar_b2b_off; + enum ntb_bar bar_num; + + if (mw_idx >= intel_ntb_mw_count(dev)) + return (EINVAL); + mw_idx = intel_ntb_user_mw_to_idx(ntb, mw_idx); + + bar_num = intel_ntb_mw_to_bar(ntb, mw_idx); + bar = &ntb->bar_info[bar_num]; + bar_b2b_off = 0; + if (mw_idx == ntb->b2b_mw_idx) { + KASSERT(ntb->b2b_off != 0, + ("user shouldn't get non-shared b2b mw")); + bar_b2b_off = ntb->b2b_off; + } + + if (bar_is_64bit(ntb, bar_num)) + limit = BUS_SPACE_MAXADDR; + else + limit = BUS_SPACE_MAXADDR_32BIT; + + if (base != NULL) + *base = bar->pbase + bar_b2b_off; + if (vbase != NULL) + *vbase = bar->vbase + bar_b2b_off; + if (size != NULL) + *size = bar->size - bar_b2b_off; + if (align != NULL) + *align = bar->size; + if (align_size != NULL) + *align_size = 1; + if (plimit != NULL) + *plimit = limit; + return (0); +} + +static int +intel_ntb_mw_set_trans(device_t dev, unsigned idx, bus_addr_t addr, size_t size) +{ + struct ntb_softc *ntb = device_get_softc(dev); + struct ntb_pci_bar_info *bar; + uint64_t base, limit, reg_val; + size_t bar_size, mw_size; + uint32_t base_reg, xlat_reg, limit_reg; + enum ntb_bar bar_num; + + if (idx >= intel_ntb_mw_count(dev)) + return (EINVAL); + idx = intel_ntb_user_mw_to_idx(ntb, idx); + + bar_num = intel_ntb_mw_to_bar(ntb, idx); + bar = &ntb->bar_info[bar_num]; + + bar_size = bar->size; + if (idx == ntb->b2b_mw_idx) + mw_size = bar_size - ntb->b2b_off; + else + mw_size = bar_size; + + /* Hardware requires that addr is aligned to bar size */ + if ((addr & (bar_size - 1)) != 0) + return (EINVAL); + + if (size > mw_size) + return (EINVAL); + + bar_get_xlat_params(ntb, bar_num, &base_reg, &xlat_reg, &limit_reg); + + limit = 0; + if (bar_is_64bit(ntb, bar_num)) { + base = intel_ntb_reg_read(8, base_reg) & BAR_HIGH_MASK; + + if (limit_reg != 0 && size != mw_size) + limit = base + size; + + /* Set and verify translation address */ + intel_ntb_reg_write(8, xlat_reg, addr); + reg_val = intel_ntb_reg_read(8, xlat_reg) & BAR_HIGH_MASK; + if (reg_val != addr) { + intel_ntb_reg_write(8, xlat_reg, 0); + return (EIO); + } + + /* Set and verify the limit */ + intel_ntb_reg_write(8, limit_reg, limit); + reg_val = intel_ntb_reg_read(8, limit_reg) & BAR_HIGH_MASK; + if (reg_val != limit) { + intel_ntb_reg_write(8, limit_reg, base); + intel_ntb_reg_write(8, xlat_reg, 0); + return (EIO); + } + } else { + /* Configure 32-bit (split) BAR MW */ + + if ((addr & UINT32_MAX) != addr) + return (ERANGE); + if (((addr + size) & UINT32_MAX) != (addr + size)) + return (ERANGE); + + base = intel_ntb_reg_read(4, base_reg) & BAR_HIGH_MASK; + + if (limit_reg != 0 && size != mw_size) + limit = base + size; + + /* Set and verify translation address */ + intel_ntb_reg_write(4, xlat_reg, addr); + reg_val = intel_ntb_reg_read(4, xlat_reg) & BAR_HIGH_MASK; + if (reg_val != addr) { + intel_ntb_reg_write(4, xlat_reg, 0); + return (EIO); + } + + /* Set and verify the limit */ + intel_ntb_reg_write(4, limit_reg, limit); + reg_val = intel_ntb_reg_read(4, limit_reg) & BAR_HIGH_MASK; + if (reg_val != limit) { + intel_ntb_reg_write(4, limit_reg, base); + intel_ntb_reg_write(4, xlat_reg, 0); + return (EIO); + } + } + return (0); +} + +static int +intel_ntb_mw_clear_trans(device_t dev, unsigned mw_idx) +{ + + return (intel_ntb_mw_set_trans(dev, mw_idx, 0, 0)); +} + +static int +intel_ntb_mw_get_wc(device_t dev, unsigned idx, vm_memattr_t *mode) +{ + struct ntb_softc *ntb = device_get_softc(dev); + struct ntb_pci_bar_info *bar; + + if (idx >= intel_ntb_mw_count(dev)) + return (EINVAL); + idx = intel_ntb_user_mw_to_idx(ntb, idx); + + bar = &ntb->bar_info[intel_ntb_mw_to_bar(ntb, idx)]; + *mode = bar->map_mode; + return (0); +} + +static int +intel_ntb_mw_set_wc(device_t dev, unsigned idx, vm_memattr_t mode) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (idx >= intel_ntb_mw_count(dev)) + return (EINVAL); + + idx = intel_ntb_user_mw_to_idx(ntb, idx); + return (intel_ntb_mw_set_wc_internal(ntb, idx, mode)); +} + +static int +intel_ntb_mw_set_wc_internal(struct ntb_softc *ntb, unsigned idx, vm_memattr_t mode) +{ + struct ntb_pci_bar_info *bar; + int rc; + + bar = &ntb->bar_info[intel_ntb_mw_to_bar(ntb, idx)]; + if (bar->map_mode == mode) + return (0); + + rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, mode); + if (rc == 0) + bar->map_mode = mode; + + return (rc); +} + +static void +intel_ntb_peer_db_set(device_t dev, uint64_t bit) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (HAS_FEATURE(ntb, NTB_SB01BASE_LOCKUP)) { + struct ntb_pci_bar_info *lapic; + unsigned i; + + lapic = ntb->peer_lapic_bar; + + for (i = 0; i < XEON_NONLINK_DB_MSIX_BITS; i++) { + if ((bit & intel_ntb_db_vector_mask(dev, i)) != 0) + bus_space_write_4(lapic->pci_bus_tag, + lapic->pci_bus_handle, + ntb->peer_msix_data[i].nmd_ofs, + ntb->peer_msix_data[i].nmd_data); + } + return; + } + + if (HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) { + intel_ntb_mw_write(2, XEON_PDOORBELL_OFFSET, bit); + return; + } + + db_iowrite(ntb, ntb->peer_reg->db_bell, bit); +} + +static int +intel_ntb_peer_db_addr(device_t dev, bus_addr_t *db_addr, vm_size_t *db_size) +{ + struct ntb_softc *ntb = device_get_softc(dev); + struct ntb_pci_bar_info *bar; + uint64_t regoff; + + KASSERT((db_addr != NULL && db_size != NULL), ("must be non-NULL")); + + if (!HAS_FEATURE(ntb, NTB_SDOORBELL_LOCKUP)) { + bar = &ntb->bar_info[NTB_CONFIG_BAR]; + regoff = ntb->peer_reg->db_bell; + } else { + KASSERT(ntb->b2b_mw_idx != B2B_MW_DISABLED, + ("invalid b2b idx")); + + bar = &ntb->bar_info[intel_ntb_mw_to_bar(ntb, ntb->b2b_mw_idx)]; + regoff = XEON_PDOORBELL_OFFSET; + } + KASSERT(bar->pci_bus_tag != X86_BUS_SPACE_IO, ("uh oh")); + + /* HACK: Specific to current x86 bus implementation. */ + *db_addr = ((uint64_t)bar->pci_bus_handle + regoff); + *db_size = ntb->reg->db_size; + return (0); +} + +static uint64_t +intel_ntb_db_valid_mask(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + return (ntb->db_valid_mask); +} + +static int +intel_ntb_db_vector_count(device_t dev) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + return (ntb->db_vec_count); +} + +static uint64_t +intel_ntb_db_vector_mask(device_t dev, uint32_t vector) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (vector > ntb->db_vec_count) + return (0); + return (ntb->db_valid_mask & intel_ntb_vec_mask(ntb, vector)); +} + +static bool +intel_ntb_link_is_up(device_t dev, enum ntb_speed *speed, enum ntb_width *width) +{ + struct ntb_softc *ntb = device_get_softc(dev); + + if (speed != NULL) + *speed = intel_ntb_link_sta_speed(ntb); + if (width != NULL) + *width = intel_ntb_link_sta_width(ntb); + return (link_is_up(ntb)); +} + +static void +save_bar_parameters(struct ntb_pci_bar_info *bar) +{ + + bar->pci_bus_tag = rman_get_bustag(bar->pci_resource); + bar->pci_bus_handle = rman_get_bushandle(bar->pci_resource); + bar->pbase = rman_get_start(bar->pci_resource); + bar->size = rman_get_size(bar->pci_resource); + bar->vbase = rman_get_virtual(bar->pci_resource); +} + +static device_method_t ntb_intel_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, intel_ntb_probe), + DEVMETHOD(device_attach, intel_ntb_attach), + DEVMETHOD(device_detach, intel_ntb_detach), + /* NTB interface */ + DEVMETHOD(ntb_link_is_up, intel_ntb_link_is_up), + DEVMETHOD(ntb_link_enable, intel_ntb_link_enable), + DEVMETHOD(ntb_link_disable, intel_ntb_link_disable), + DEVMETHOD(ntb_link_enabled, intel_ntb_link_enabled), + DEVMETHOD(ntb_mw_count, intel_ntb_mw_count), + DEVMETHOD(ntb_mw_get_range, intel_ntb_mw_get_range), + DEVMETHOD(ntb_mw_set_trans, intel_ntb_mw_set_trans), + DEVMETHOD(ntb_mw_clear_trans, intel_ntb_mw_clear_trans), + DEVMETHOD(ntb_mw_get_wc, intel_ntb_mw_get_wc), + DEVMETHOD(ntb_mw_set_wc, intel_ntb_mw_set_wc), + DEVMETHOD(ntb_spad_count, intel_ntb_spad_count), + DEVMETHOD(ntb_spad_clear, intel_ntb_spad_clear), + DEVMETHOD(ntb_spad_write, intel_ntb_spad_write), + DEVMETHOD(ntb_spad_read, intel_ntb_spad_read), + DEVMETHOD(ntb_peer_spad_write, intel_ntb_peer_spad_write), + DEVMETHOD(ntb_peer_spad_read, intel_ntb_peer_spad_read), + DEVMETHOD(ntb_db_valid_mask, intel_ntb_db_valid_mask), + DEVMETHOD(ntb_db_vector_count, intel_ntb_db_vector_count), + DEVMETHOD(ntb_db_vector_mask, intel_ntb_db_vector_mask), + DEVMETHOD(ntb_db_clear, intel_ntb_db_clear), + DEVMETHOD(ntb_db_clear_mask, intel_ntb_db_clear_mask), + DEVMETHOD(ntb_db_read, intel_ntb_db_read), + DEVMETHOD(ntb_db_set_mask, intel_ntb_db_set_mask), + DEVMETHOD(ntb_peer_db_addr, intel_ntb_peer_db_addr), + DEVMETHOD(ntb_peer_db_set, intel_ntb_peer_db_set), + DEVMETHOD_END +}; + +static DEFINE_CLASS_0(ntb_hw, ntb_intel_driver, ntb_intel_methods, + sizeof(struct ntb_softc)); +DRIVER_MODULE(ntb_hw_intel, pci, ntb_intel_driver, ntb_hw_devclass, NULL, NULL); +MODULE_DEPEND(ntb_hw_intel, ntb, 1, 1, 1); +MODULE_VERSION(ntb_hw_intel, 1); Property changes on: stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.c ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.h =================================================================== --- stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.h (nonexistent) +++ stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.h (revision 323453) @@ -0,0 +1,168 @@ +/*- + * Copyright (c) 2016 Alexander Motin + * Copyright (C) 2013 Intel Corporation + * Copyright (C) 2015 EMC Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _NTB_REGS_H_ +#define _NTB_REGS_H_ + +#define NTB_LINK_STATUS_ACTIVE 0x2000 +#define NTB_LINK_SPEED_MASK 0x000f +#define NTB_LINK_WIDTH_MASK 0x03f0 +#define NTB_LNK_STA_WIDTH(sta) (((sta) & NTB_LINK_WIDTH_MASK) >> 4) + +#define XEON_SNB_MW_COUNT 2 +#define XEON_HSX_SPLIT_MW_COUNT 3 +/* Reserve the uppermost bit for link interrupt */ +#define XEON_DB_COUNT 15 +#define XEON_DB_TOTAL_SHIFT 16 +#define XEON_DB_LINK 15 +#define XEON_DB_MSIX_VECTOR_COUNT 4 +#define XEON_DB_MSIX_VECTOR_SHIFT 5 +#define XEON_DB_LINK_BIT (1 << XEON_DB_LINK) +#define XEON_NONLINK_DB_MSIX_BITS 3 + +#define XEON_SPCICMD_OFFSET 0x0504 +#define XEON_DEVCTRL_OFFSET 0x0598 +#define XEON_DEVSTS_OFFSET 0x059a +#define XEON_LINK_STATUS_OFFSET 0x01a2 +#define XEON_SLINK_STATUS_OFFSET 0x05a2 + +#define XEON_PBAR2LMT_OFFSET 0x0000 +#define XEON_PBAR4LMT_OFFSET 0x0008 +#define XEON_PBAR5LMT_OFFSET 0x000c +#define XEON_PBAR2XLAT_OFFSET 0x0010 +#define XEON_PBAR4XLAT_OFFSET 0x0018 +#define XEON_PBAR5XLAT_OFFSET 0x001c +#define XEON_SBAR2LMT_OFFSET 0x0020 +#define XEON_SBAR4LMT_OFFSET 0x0028 +#define XEON_SBAR5LMT_OFFSET 0x002c +#define XEON_SBAR2XLAT_OFFSET 0x0030 +#define XEON_SBAR4XLAT_OFFSET 0x0038 +#define XEON_SBAR5XLAT_OFFSET 0x003c +#define XEON_SBAR0BASE_OFFSET 0x0040 +#define XEON_SBAR2BASE_OFFSET 0x0048 +#define XEON_SBAR4BASE_OFFSET 0x0050 +#define XEON_SBAR5BASE_OFFSET 0x0054 +#define XEON_NTBCNTL_OFFSET 0x0058 +#define XEON_SBDF_OFFSET 0x005c +#define XEON_PDOORBELL_OFFSET 0x0060 +#define XEON_PDBMSK_OFFSET 0x0062 +#define XEON_SDOORBELL_OFFSET 0x0064 +#define XEON_SDBMSK_OFFSET 0x0066 +#define XEON_USMEMMISS_OFFSET 0x0070 +#define XEON_SPAD_OFFSET 0x0080 +#define XEON_SPAD_COUNT 16 +#define XEON_SPADSEMA4_OFFSET 0x00c0 +#define XEON_WCCNTRL_OFFSET 0x00e0 +#define XEON_UNCERRSTS_OFFSET 0x014c +#define XEON_CORERRSTS_OFFSET 0x0158 +#define XEON_B2B_SPAD_OFFSET 0x0100 +#define XEON_B2B_DOORBELL_OFFSET 0x0140 +#define XEON_B2B_XLAT_OFFSETL 0x0144 +#define XEON_B2B_XLAT_OFFSETU 0x0148 + +#define ATOM_MW_COUNT 2 +#define ATOM_DB_COUNT 34 +#define ATOM_DB_MSIX_VECTOR_COUNT 34 +#define ATOM_DB_MSIX_VECTOR_SHIFT 1 + +#define ATOM_SPCICMD_OFFSET 0xb004 +#define ATOM_MBAR23_OFFSET 0xb018 +#define ATOM_MBAR45_OFFSET 0xb020 +#define ATOM_DEVCTRL_OFFSET 0xb048 +#define ATOM_LINK_STATUS_OFFSET 0xb052 +#define ATOM_ERRCORSTS_OFFSET 0xb110 + +#define ATOM_SBAR2XLAT_OFFSET 0x0008 +#define ATOM_SBAR4XLAT_OFFSET 0x0010 +#define ATOM_PDOORBELL_OFFSET 0x0020 +#define ATOM_PDBMSK_OFFSET 0x0028 +#define ATOM_NTBCNTL_OFFSET 0x0060 +#define ATOM_EBDF_OFFSET 0x0064 +#define ATOM_SPAD_OFFSET 0x0080 +#define ATOM_SPAD_COUNT 16 +#define ATOM_SPADSEMA_OFFSET 0x00c0 +#define ATOM_STKYSPAD_OFFSET 0x00c4 +#define ATOM_PBAR2XLAT_OFFSET 0x8008 +#define ATOM_PBAR4XLAT_OFFSET 0x8010 +#define ATOM_B2B_DOORBELL_OFFSET 0x8020 +#define ATOM_B2B_SPAD_OFFSET 0x8080 +#define ATOM_B2B_SPADSEMA_OFFSET 0x80c0 +#define ATOM_B2B_STKYSPAD_OFFSET 0x80c4 + +#define ATOM_MODPHY_PCSREG4 0x1c004 +#define ATOM_MODPHY_PCSREG6 0x1c006 + +#define ATOM_IP_BASE 0xc000 +#define ATOM_DESKEWSTS_OFFSET (ATOM_IP_BASE + 0x3024) +#define ATOM_LTSSMERRSTS0_OFFSET (ATOM_IP_BASE + 0x3180) +#define ATOM_LTSSMSTATEJMP_OFFSET (ATOM_IP_BASE + 0x3040) +#define ATOM_IBSTERRRCRVSTS0_OFFSET (ATOM_IP_BASE + 0x3324) + +#define ATOM_DESKEWSTS_DBERR (1 << 15) +#define ATOM_LTSSMERRSTS0_UNEXPECTEDEI (1 << 20) +#define ATOM_LTSSMSTATEJMP_FORCEDETECT (1 << 2) +#define ATOM_IBIST_ERR_OFLOW 0x7fff7fff + +#define NTB_CNTL_CFG_LOCK (1 << 0) +#define NTB_CNTL_LINK_DISABLE (1 << 1) +#define NTB_CNTL_S2P_BAR23_SNOOP (1 << 2) +#define NTB_CNTL_P2S_BAR23_SNOOP (1 << 4) +#define NTB_CNTL_S2P_BAR4_SNOOP (1 << 6) +#define NTB_CNTL_P2S_BAR4_SNOOP (1 << 8) +#define NTB_CNTL_S2P_BAR5_SNOOP (1 << 12) +#define NTB_CNTL_P2S_BAR5_SNOOP (1 << 14) +#define ATOM_CNTL_LINK_DOWN (1 << 16) + +#define XEON_PBAR23SZ_OFFSET 0x00d0 +#define XEON_PBAR45SZ_OFFSET 0x00d1 +#define XEON_PBAR4SZ_OFFSET 0x00d1 +#define XEON_PBAR5SZ_OFFSET 0x00d5 +#define XEON_SBAR23SZ_OFFSET 0x00d2 +#define XEON_SBAR4SZ_OFFSET 0x00d3 +#define XEON_SBAR5SZ_OFFSET 0x00d6 +#define NTB_PPD_OFFSET 0x00d4 +#define XEON_PPD_CONN_TYPE 0x0003 +#define XEON_PPD_DEV_TYPE 0x0010 +#define XEON_PPD_SPLIT_BAR 0x0040 +#define ATOM_PPD_INIT_LINK 0x0008 +#define ATOM_PPD_CONN_TYPE 0x0300 +#define ATOM_PPD_DEV_TYPE 0x1000 + +/* All addresses are in low 32-bit space so 32-bit BARs can function */ +#define XEON_B2B_BAR0_ADDR 0x1000000000000000ull +#define XEON_B2B_BAR2_ADDR64 0x2000000000000000ull +#define XEON_B2B_BAR4_ADDR64 0x4000000000000000ull +#define XEON_B2B_BAR4_ADDR32 0x20000000ull +#define XEON_B2B_BAR5_ADDR32 0x40000000ull + +/* The peer ntb secondary config space is 32KB fixed size */ +#define XEON_B2B_MIN_SIZE 0x8000 + +#endif /* _NTB_REGS_H_ */ Property changes on: stable/11/sys/dev/ntb/ntb_hw/ntb_hw_intel.h ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: stable/11/sys/dev/ntb/ntb_hw/ntb_hw_plx.c =================================================================== --- stable/11/sys/dev/ntb/ntb_hw/ntb_hw_plx.c (nonexistent) +++ stable/11/sys/dev/ntb/ntb_hw/ntb_hw_plx.c (revision 323453) @@ -0,0 +1,950 @@ +/*- + * Copyright (c) 2017 Alexander Motin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * The Non-Transparent Bridge (NTB) is a device that allows you to connect + * two or more systems using a PCI-e links, providing remote memory access. + * + * This module contains a driver for NTBs in PLX/Avago/Broadcom PCIe bridges. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../ntb.h" + +#define PLX_MAX_BARS 4 /* There are at most 4 data BARs. */ +#define PLX_NUM_SPAD 8 /* There are 8 scratchpads. */ +#define PLX_NUM_SPAD_PATT 4 /* Use test pattern as 4 more. */ +#define PLX_NUM_DB 16 /* There are 16 doorbells. */ + +struct ntb_plx_mw_info { + int mw_bar; + int mw_64bit; + int mw_rid; + struct resource *mw_res; + vm_paddr_t mw_pbase; + caddr_t mw_vbase; + vm_size_t mw_size; + vm_memattr_t mw_map_mode; + bus_addr_t mw_xlat_addr; + size_t mw_xlat_size; +}; + +struct ntb_plx_softc { + /* ntb.c context. Do not move! Must go first! */ + void *ntb_store; + + device_t dev; + struct resource *conf_res; + int conf_rid; + u_int ntx; /* NTx number within chip. */ + u_int link; /* Link v/s Virtual side. */ + u_int port; /* Port number within chip. */ + + int int_rid; + struct resource *int_res; + void *int_tag; + + struct ntb_plx_mw_info mw_info[PLX_MAX_BARS]; + int mw_count; /* Number of memory windows. */ + + int spad_count1; /* Number of standard spads. */ + int spad_count2; /* Number of extra spads. */ + uint32_t spad_off1; /* Offset of our spads. */ + uint32_t spad_off2; /* Offset of our extra spads. */ + uint32_t spad_offp1; /* Offset of peer spads. */ + uint32_t spad_offp2; /* Offset of peer extra spads. */ + + /* Parameters of window shared with peer config access in B2B mode. */ + int b2b_mw; /* Shared window number. */ + uint64_t b2b_off; /* Offset in shared window. */ +}; + +#define PLX_NT0_BASE 0x3E000 +#define PLX_NT1_BASE 0x3C000 +#define PLX_NTX_BASE(sc) ((sc)->ntx ? PLX_NT1_BASE : PLX_NT0_BASE) +#define PLX_NTX_LINK_OFFSET 0x01000 + +/* Bases of NTx our/peer interface registers */ +#define PLX_NTX_OUR_BASE(sc) \ + (PLX_NTX_BASE(sc) + ((sc)->link ? PLX_NTX_LINK_OFFSET : 0)) +#define PLX_NTX_PEER_BASE(sc) \ + (PLX_NTX_BASE(sc) + ((sc)->link ? 0 : PLX_NTX_LINK_OFFSET)) + +/* Read/write NTx our interface registers */ +#define NTX_READ(sc, reg) \ + bus_read_4((sc)->conf_res, PLX_NTX_OUR_BASE(sc) + (reg)) +#define NTX_WRITE(sc, reg, val) \ + bus_write_4((sc)->conf_res, PLX_NTX_OUR_BASE(sc) + (reg), (val)) + +/* Read/write NTx peer interface registers */ +#define PNTX_READ(sc, reg) \ + bus_read_4((sc)->conf_res, PLX_NTX_PEER_BASE(sc) + (reg)) +#define PNTX_WRITE(sc, reg, val) \ + bus_write_4((sc)->conf_res, PLX_NTX_PEER_BASE(sc) + (reg), (val)) + +/* Read/write B2B NTx registers */ +#define BNTX_READ(sc, reg) \ + bus_read_4((sc)->mw_info[(sc)->b2b_mw].mw_res, \ + PLX_NTX_BASE(sc) + (reg)) +#define BNTX_WRITE(sc, reg, val) \ + bus_write_4((sc)->mw_info[(sc)->b2b_mw].mw_res, \ + PLX_NTX_BASE(sc) + (reg), (val)) + +#define PLX_PORT_BASE(p) ((p) << 12) +#define PLX_STATION_PORT_BASE(sc) PLX_PORT_BASE((sc)->port & ~7) + +#define PLX_PORT_CONTROL(sc) (PLX_STATION_PORT_BASE(sc) + 0x208) + +static int ntb_plx_init(device_t dev); +static int ntb_plx_detach(device_t dev); +static int ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx); + +static int +ntb_plx_probe(device_t dev) +{ + + switch (pci_get_devid(dev)) { + case 0x87a010b5: + device_set_desc(dev, "PLX Non-Transparent Bridge NT0 Link"); + return (BUS_PROBE_DEFAULT); + case 0x87a110b5: + device_set_desc(dev, "PLX Non-Transparent Bridge NT1 Link"); + return (BUS_PROBE_DEFAULT); + case 0x87b010b5: + device_set_desc(dev, "PLX Non-Transparent Bridge NT0 Virtual"); + return (BUS_PROBE_DEFAULT); + case 0x87b110b5: + device_set_desc(dev, "PLX Non-Transparent Bridge NT1 Virtual"); + return (BUS_PROBE_DEFAULT); + } + return (ENXIO); +} + +static int +ntb_plx_init(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + uint64_t val64; + int i; + uint32_t val; + + if (sc->b2b_mw >= 0) { + /* Set peer BAR0/1 size and address for B2B NTx access. */ + mw = &sc->mw_info[sc->b2b_mw]; + if (mw->mw_64bit) { + PNTX_WRITE(sc, 0xe4, 0x3); /* 64-bit */ + val64 = 0x2000000000000000 * mw->mw_bar | 0x4; + PNTX_WRITE(sc, PCIR_BAR(0), val64); + PNTX_WRITE(sc, PCIR_BAR(0) + 4, val64 >> 32); + } else { + PNTX_WRITE(sc, 0xe4, 0x2); /* 32-bit */ + val = 0x20000000 * mw->mw_bar; + PNTX_WRITE(sc, PCIR_BAR(0), val); + } + + /* Set Virtual to Link address translation for B2B. */ + for (i = 0; i < sc->mw_count; i++) { + mw = &sc->mw_info[i]; + if (mw->mw_64bit) { + val64 = 0x2000000000000000 * mw->mw_bar; + NTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, val64); + NTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4 + 4, val64 >> 32); + } else { + val = 0x20000000 * mw->mw_bar; + NTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, val); + } + } + + /* Enable Link Interface LUT entry 0 for 0:0.0. */ + PNTX_WRITE(sc, 0xdb4, 1); + } + + /* + * Enable Virtual Interface LUT entry 0 for 0:0.0 and + * entry 1 for our Requester ID reported by chip. + */ + val = (NTX_READ(sc, 0xc90) << 16) | 0x00010001; + NTX_WRITE(sc, sc->link ? 0xdb4 : 0xd94, val); + + /* Set Link to Virtual address translation. */ + for (i = 0; i < sc->mw_count; i++) { + mw = &sc->mw_info[i]; + if (mw->mw_xlat_size != 0) + ntb_plx_mw_set_trans_internal(dev, i); + } + + pci_enable_busmaster(dev); + if (sc->b2b_mw >= 0) + PNTX_WRITE(sc, PCIR_COMMAND, PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + + return (0); +} + +static void +ntb_plx_isr(void *arg) +{ + device_t dev = arg; + struct ntb_plx_softc *sc = device_get_softc(dev); + uint32_t val; + + ntb_db_event((device_t)arg, 0); + + if (sc->link) /* Link Interface has no Link Error registers. */ + return; + + val = NTX_READ(sc, 0xfe0); + if (val == 0) + return; + NTX_WRITE(sc, 0xfe0, val); + if (val & 1) + device_printf(dev, "Correctable Error\n"); + if (val & 2) + device_printf(dev, "Uncorrectable Error\n"); + if (val & 4) { + /* DL_Down resets link side registers, have to reinit. */ + ntb_plx_init(dev); + ntb_link_event(dev); + } + if (val & 8) + device_printf(dev, "Uncorrectable Error Message Drop\n"); +} + +static int +ntb_plx_setup_intr(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + int error; + + /* + * XXX: This hardware supports MSI, but I found it unusable. + * It generates new MSI only when doorbell register goes from + * zero, but does not generate it when another bit is set or on + * partial clear. It makes operation very racy and unreliable. + * The data book mentions some mask juggling magic to workaround + * that, but I failed to make it work. + */ + sc->int_rid = 0; + sc->int_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->int_rid, RF_SHAREABLE|RF_ACTIVE); + if (sc->int_res == NULL) { + device_printf(dev, "bus_alloc_resource failed\n"); + return (ENOMEM); + } + error = bus_setup_intr(dev, sc->int_res, INTR_MPSAFE | INTR_TYPE_MISC, + NULL, ntb_plx_isr, dev, &sc->int_tag); + if (error != 0) { + device_printf(dev, "bus_setup_intr failed: %d\n", error); + return (error); + } + + if (!sc->link) { /* Link Interface has no Link Error registers. */ + NTX_WRITE(sc, 0xfe0, 0xf); /* Clear link interrupts. */ + NTX_WRITE(sc, 0xfe4, 0x0); /* Unmask link interrupts. */ + } + return (0); +} + +static void +ntb_plx_teardown_intr(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + if (!sc->link) /* Link Interface has no Link Error registers. */ + NTX_WRITE(sc, 0xfe4, 0xf); /* Mask link interrupts. */ + + if (sc->int_res) { + bus_teardown_intr(dev, sc->int_res, sc->int_tag); + bus_release_resource(dev, SYS_RES_IRQ, sc->int_rid, + sc->int_res); + } +} + +static int +ntb_plx_attach(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + int error = 0, i; + uint32_t val; + char buf[32]; + + /* Identify what we are (what side of what NTx). */ + sc->dev = dev; + val = pci_read_config(dev, 0xc8c, 4); + sc->ntx = (val & 1) != 0; + sc->link = (val & 0x80000000) != 0; + + /* Get access to whole 256KB of chip configuration space via BAR0/1. */ + sc->conf_rid = PCIR_BAR(0); + sc->conf_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->conf_rid, RF_ACTIVE); + if (sc->conf_res == NULL) { + device_printf(dev, "Can't allocate configuration BAR.\n"); + return (ENXIO); + } + + /* Identify chip port we are connected to. */ + val = bus_read_4(sc->conf_res, 0x360); + sc->port = (val >> ((sc->ntx == 0) ? 8 : 16)) & 0x1f; + + /* Find configured memory windows at BAR2-5. */ + sc->mw_count = 0; + for (i = 2; i <= 5; i++) { + mw = &sc->mw_info[sc->mw_count]; + mw->mw_bar = i; + mw->mw_rid = PCIR_BAR(mw->mw_bar); + mw->mw_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &mw->mw_rid, RF_ACTIVE); + if (mw->mw_res == NULL) + continue; + mw->mw_pbase = rman_get_start(mw->mw_res); + mw->mw_size = rman_get_size(mw->mw_res); + mw->mw_vbase = rman_get_virtual(mw->mw_res); + mw->mw_map_mode = VM_MEMATTR_UNCACHEABLE; + sc->mw_count++; + + /* Skip over adjacent BAR for 64-bit BARs. */ + val = pci_read_config(dev, PCIR_BAR(mw->mw_bar), 4); + if ((val & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64) { + mw->mw_64bit = 1; + i++; + } + } + + /* Try to identify B2B mode. */ + i = 1; + snprintf(buf, sizeof(buf), "hint.%s.%d.b2b", device_get_name(dev), + device_get_unit(dev)); + TUNABLE_INT_FETCH(buf, &i); + if (sc->link) { + device_printf(dev, "NTB-to-Root Port mode (Link Interface)\n"); + sc->b2b_mw = -1; + } else if (i == 0) { + device_printf(dev, "NTB-to-Root Port mode (Virtual Interface)\n"); + sc->b2b_mw = -1; + } else { + device_printf(dev, "NTB-to-NTB (back-to-back) mode\n"); + + /* We need at least one memory window for B2B peer access. */ + if (sc->mw_count == 0) { + device_printf(dev, "No memory window BARs enabled.\n"); + error = ENXIO; + goto out; + } + sc->b2b_mw = sc->mw_count - 1; + + /* Use half of the window for B2B, but no less then 1MB. */ + mw = &sc->mw_info[sc->b2b_mw]; + if (mw->mw_size >= 2 * 1024 * 1024) + sc->b2b_off = mw->mw_size / 2; + else + sc->b2b_off = 0; + } + + /* + * Use Physical Layer User Test Pattern as additional scratchpad. + * Make sure they are present and enabled by writing to them. + * XXX: Its a hack, but standard 8 registers are not enough. + */ + sc->spad_offp1 = sc->spad_off1 = PLX_NTX_OUR_BASE(sc) + 0xc6c; + sc->spad_offp2 = sc->spad_off2 = PLX_PORT_BASE(sc->ntx * 8) + 0x20c; + if (sc->b2b_mw >= 0) { + /* In NTB-to-NTB mode each side has own scratchpads. */ + sc->spad_count1 = PLX_NUM_SPAD; + bus_write_4(sc->conf_res, sc->spad_off2, 0x12345678); + if (bus_read_4(sc->conf_res, sc->spad_off2) == 0x12345678) + sc->spad_count2 = PLX_NUM_SPAD_PATT; + } else { + /* Otherwise we have share scratchpads with the peer. */ + if (sc->link) { + sc->spad_off1 += PLX_NUM_SPAD / 2 * 4; + sc->spad_off2 += PLX_NUM_SPAD_PATT / 2 * 4; + } else { + sc->spad_offp1 += PLX_NUM_SPAD / 2 * 4; + sc->spad_offp2 += PLX_NUM_SPAD_PATT / 2 * 4; + } + sc->spad_count1 = PLX_NUM_SPAD / 2; + bus_write_4(sc->conf_res, sc->spad_off2, 0x12345678); + if (bus_read_4(sc->conf_res, sc->spad_off2) == 0x12345678) + sc->spad_count2 = PLX_NUM_SPAD_PATT / 2; + } + + /* Apply static part of NTB configuration. */ + ntb_plx_init(dev); + + /* Allocate and setup interrupts. */ + error = ntb_plx_setup_intr(dev); + if (error) + goto out; + + /* Attach children to this controller */ + error = ntb_register_device(dev); + +out: + if (error != 0) + ntb_plx_detach(dev); + return (error); +} + +static int +ntb_plx_detach(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + int i; + + /* Detach & delete all children */ + ntb_unregister_device(dev); + + /* Disable and free interrupts. */ + ntb_plx_teardown_intr(dev); + + /* Free memory resources. */ + for (i = 0; i < sc->mw_count; i++) { + mw = &sc->mw_info[i]; + bus_release_resource(dev, SYS_RES_MEMORY, mw->mw_rid, + mw->mw_res); + } + bus_release_resource(dev, SYS_RES_MEMORY, sc->conf_rid, sc->conf_res); + return (0); +} + + +static bool +ntb_plx_link_is_up(device_t dev, enum ntb_speed *speed, enum ntb_width *width) +{ + uint16_t link; + + link = pcie_read_config(dev, PCIER_LINK_STA, 2); + if (speed != NULL) + *speed = (link & PCIEM_LINK_STA_SPEED); + if (width != NULL) + *width = (link & PCIEM_LINK_STA_WIDTH) >> 4; + return ((link & PCIEM_LINK_STA_WIDTH) != 0); +} + +static int +ntb_plx_link_enable(device_t dev, enum ntb_speed speed __unused, + enum ntb_width width __unused) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + uint32_t reg, val; + + /* The fact that we see the Link Interface means link is enabled. */ + if (sc->link) { + ntb_link_event(dev); + return (0); + } + + reg = PLX_PORT_CONTROL(sc); + val = bus_read_4(sc->conf_res, reg); + if ((val & (1 << (sc->port & 7))) == 0) { + /* If already enabled, generate fake link event and exit. */ + ntb_link_event(dev); + return (0); + } + val &= ~(1 << (sc->port & 7)); + bus_write_4(sc->conf_res, reg, val); + return (0); +} + +static int +ntb_plx_link_disable(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + uint32_t reg, val; + + /* Link disable for Link Interface would be suicidal. */ + if (sc->link) + return (0); + + reg = PLX_PORT_CONTROL(sc); + val = bus_read_4(sc->conf_res, reg); + val |= (1 << (sc->port & 7)); + bus_write_4(sc->conf_res, reg, val); + return (0); +} + +static bool +ntb_plx_link_enabled(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + uint32_t reg, val; + + /* The fact that we see the Link Interface means link is enabled. */ + if (sc->link) + return (TRUE); + + reg = PLX_PORT_CONTROL(sc); + val = bus_read_4(sc->conf_res, reg); + return ((val & (1 << (sc->port & 7))) == 0); +} + +static uint8_t +ntb_plx_mw_count(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + if (sc->b2b_mw >= 0 && sc->b2b_off == 0) + return (sc->mw_count - 1); /* B2B consumed whole window. */ + return (sc->mw_count); +} + +static int +ntb_plx_mw_get_range(device_t dev, unsigned mw_idx, vm_paddr_t *base, + caddr_t *vbase, size_t *size, size_t *align, size_t *align_size, + bus_addr_t *plimit) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + size_t off; + + if (mw_idx >= sc->mw_count) + return (EINVAL); + off = 0; + if (mw_idx == sc->b2b_mw) { + KASSERT(sc->b2b_off != 0, + ("user shouldn't get non-shared b2b mw")); + off = sc->b2b_off; + } + mw = &sc->mw_info[mw_idx]; + + /* Local to remote memory window parameters. */ + if (base != NULL) + *base = mw->mw_pbase + off; + if (vbase != NULL) + *vbase = mw->mw_vbase + off; + if (size != NULL) + *size = mw->mw_size - off; + + /* + * Remote to local memory window translation address alignment. + * XXX: In B2B mode we can change window size (and so alignmet) + * live, but there is no way to report it, so report safe value. + */ + if (align != NULL) + *align = mw->mw_size - off; + + /* + * Remote to local memory window size alignment. + * XXX: The chip has no limit registers. In B2B case size must be + * power of 2 (since we can reprogram BAR size), but there is no way + * to report it, so report 1MB -- minimal BAR size. In non-B2B case + * there is no control at all, so report the precofigured BAR size. + */ + if (align_size != NULL) { + if (sc->b2b_mw >= 0) + *align_size = 1024 * 1024; + else + *align_size = mw->mw_size - off; + } + + /* Remote to local memory window translation address upper limit. */ + if (plimit != NULL) + *plimit = mw->mw_64bit ? BUS_SPACE_MAXADDR : + BUS_SPACE_MAXADDR_32BIT; + return (0); +} + +static int +ntb_plx_mw_set_trans_internal(device_t dev, unsigned mw_idx) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + uint64_t addr, off, size, val64; + uint32_t val; + + mw = &sc->mw_info[mw_idx]; + addr = mw->mw_xlat_addr; + size = mw->mw_xlat_size; + off = 0; + if (mw_idx == sc->b2b_mw) { + off = sc->b2b_off; + KASSERT(off != 0, ("user shouldn't get non-shared b2b mw")); + + /* + * While generally we can set any BAR size on link side, + * for B2B shared window we can't go above preconfigured + * size due to BAR address alignment requirements. + */ + if (size > mw->mw_size - off) + return (EINVAL); + } + + if (size > 0) { + /* Round BAR size to next power of 2 or at least 1MB. */ + if (!powerof2(size)) + size = 1LL << flsll(size); + if (size < 1024 * 1024) + size = 1024 * 1024; + + /* Hardware requires addr aligned to BAR size. */ + if ((addr & (size - 1)) != 0) + return (EINVAL); + } + + if (mw->mw_64bit) { + if (sc->b2b_mw >= 0) { + /* Set Link Interface BAR size and enable/disable it. */ + val64 = 0; + if (size > 0) + val64 = (~(size - 1) & ~0xfffff); + val64 |= 0x4; + PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4, val64); + PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4 + 4, val64 >> 32); + + /* Set Link Interface BAR address. */ + val64 = 0x2000000000000000 * mw->mw_bar + off; + val64 |= 0x4; + PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar), val64); + PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar) + 4, val64 >> 32); + } + + /* Set Virtual Interface BARs address translation */ + PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, addr); + PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4 + 4, addr >> 32); + } else { + /* Make sure we fit into 32-bit address space. */ + if ((addr & UINT32_MAX) != addr) + return (ERANGE); + if (((addr + size) & UINT32_MAX) != (addr + size)) + return (ERANGE); + + if (sc->b2b_mw >= 0) { + /* Set Link Interface BAR size and enable/disable it. */ + val = 0; + if (size > 0) + val = (~(size - 1) & ~0xfffff); + PNTX_WRITE(sc, 0xe8 + (mw->mw_bar - 2) * 4, val); + + /* Set Link Interface BAR address. */ + val64 = 0x20000000 * mw->mw_bar + off; + PNTX_WRITE(sc, PCIR_BAR(mw->mw_bar), val64); + } + + /* Set Virtual Interface BARs address translation */ + PNTX_WRITE(sc, 0xc3c + (mw->mw_bar - 2) * 4, addr); + } + return (0); +} + +static int +ntb_plx_mw_set_trans(device_t dev, unsigned mw_idx, bus_addr_t addr, size_t size) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + + if (mw_idx >= sc->mw_count) + return (EINVAL); + mw = &sc->mw_info[mw_idx]; + mw->mw_xlat_addr = addr; + mw->mw_xlat_size = size; + return (ntb_plx_mw_set_trans_internal(dev, mw_idx)); +} + +static int +ntb_plx_mw_clear_trans(device_t dev, unsigned mw_idx) +{ + + return (ntb_plx_mw_set_trans(dev, mw_idx, 0, 0)); +} + +static int +ntb_plx_mw_get_wc(device_t dev, unsigned idx, vm_memattr_t *mode) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + + if (idx >= sc->mw_count) + return (EINVAL); + mw = &sc->mw_info[idx]; + *mode = mw->mw_map_mode; + return (0); +} + +static int +ntb_plx_mw_set_wc(device_t dev, unsigned idx, vm_memattr_t mode) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + uint64_t off; + int rc; + + if (idx >= sc->mw_count) + return (EINVAL); + mw = &sc->mw_info[idx]; + if (mw->mw_map_mode == mode) + return (0); + + off = 0; + if (idx == sc->b2b_mw) { + KASSERT(sc->b2b_off != 0, + ("user shouldn't get non-shared b2b mw")); + off = sc->b2b_off; + } + + rc = pmap_change_attr((vm_offset_t)mw->mw_vbase + off, + mw->mw_size - off, mode); + if (rc == 0) + mw->mw_map_mode = mode; + return (rc); +} + +static uint8_t +ntb_plx_spad_count(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + return (sc->spad_count1 + sc->spad_count2); +} + +static int +ntb_plx_spad_write(device_t dev, unsigned int idx, uint32_t val) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + u_int off; + + if (idx >= sc->spad_count1 + sc->spad_count2) + return (EINVAL); + + if (idx < sc->spad_count1) + off = sc->spad_off1 + idx * 4; + else + off = sc->spad_off2 + (idx - sc->spad_count1) * 4; + bus_write_4(sc->conf_res, off, val); + return (0); +} + +static void +ntb_plx_spad_clear(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + int i; + + for (i = 0; i < sc->spad_count1 + sc->spad_count2; i++) + ntb_plx_spad_write(dev, i, 0); +} + +static int +ntb_plx_spad_read(device_t dev, unsigned int idx, uint32_t *val) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + u_int off; + + if (idx >= sc->spad_count1 + sc->spad_count2) + return (EINVAL); + + if (idx < sc->spad_count1) + off = sc->spad_off1 + idx * 4; + else + off = sc->spad_off2 + (idx - sc->spad_count1) * 4; + *val = bus_read_4(sc->conf_res, off); + return (0); +} + +static int +ntb_plx_peer_spad_write(device_t dev, unsigned int idx, uint32_t val) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + u_int off; + + if (idx >= sc->spad_count1 + sc->spad_count2) + return (EINVAL); + + if (idx < sc->spad_count1) + off = sc->spad_offp1 + idx * 4; + else + off = sc->spad_offp2 + (idx - sc->spad_count1) * 4; + if (sc->b2b_mw >= 0) + bus_write_4(sc->mw_info[sc->b2b_mw].mw_res, off, val); + else + bus_write_4(sc->conf_res, off, val); + return (0); +} + +static int +ntb_plx_peer_spad_read(device_t dev, unsigned int idx, uint32_t *val) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + u_int off; + + if (idx >= sc->spad_count1 + sc->spad_count2) + return (EINVAL); + + if (idx < sc->spad_count1) + off = sc->spad_offp1 + idx * 4; + else + off = sc->spad_offp2 + (idx - sc->spad_count1) * 4; + if (sc->b2b_mw >= 0) + *val = bus_read_4(sc->mw_info[sc->b2b_mw].mw_res, off); + else + *val = bus_read_4(sc->conf_res, off); + return (0); +} + +static uint64_t +ntb_plx_db_valid_mask(device_t dev) +{ + + return ((1LL << PLX_NUM_DB) - 1); +} + +static int +ntb_plx_db_vector_count(device_t dev) +{ + + return (1); +} + +static uint64_t +ntb_plx_db_vector_mask(device_t dev, uint32_t vector) +{ + + if (vector > 0) + return (0); + return ((1LL << PLX_NUM_DB) - 1); +} + +static void +ntb_plx_db_clear(device_t dev, uint64_t bits) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + NTX_WRITE(sc, sc->link ? 0xc60 : 0xc50, bits); +} + +static void +ntb_plx_db_clear_mask(device_t dev, uint64_t bits) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + NTX_WRITE(sc, sc->link ? 0xc68 : 0xc58, bits); +} + +static uint64_t +ntb_plx_db_read(device_t dev) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + return (NTX_READ(sc, sc->link ? 0xc5c : 0xc4c)); +} + +static void +ntb_plx_db_set_mask(device_t dev, uint64_t bits) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + NTX_WRITE(sc, sc->link ? 0xc64 : 0xc54, bits); +} + +static int +ntb_plx_peer_db_addr(device_t dev, bus_addr_t *db_addr, vm_size_t *db_size) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + struct ntb_plx_mw_info *mw; + + KASSERT((db_addr != NULL && db_size != NULL), ("must be non-NULL")); + + if (sc->b2b_mw >= 0) { + mw = &sc->mw_info[sc->b2b_mw]; + *db_addr = (uint64_t)mw->mw_pbase + PLX_NTX_BASE(sc) + 0xc4c; + } else { + *db_addr = rman_get_start(sc->conf_res) + PLX_NTX_BASE(sc); + *db_addr += sc->link ? 0xc4c : 0xc5c; + } + *db_size = 4; + return (0); +} + +static void +ntb_plx_peer_db_set(device_t dev, uint64_t bit) +{ + struct ntb_plx_softc *sc = device_get_softc(dev); + + if (sc->b2b_mw >= 0) + BNTX_WRITE(sc, 0xc4c, bit); + else + NTX_WRITE(sc, sc->link ? 0xc4c : 0xc5c, bit); +} + +static device_method_t ntb_plx_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ntb_plx_probe), + DEVMETHOD(device_attach, ntb_plx_attach), + DEVMETHOD(device_detach, ntb_plx_detach), + /* NTB interface */ + DEVMETHOD(ntb_link_is_up, ntb_plx_link_is_up), + DEVMETHOD(ntb_link_enable, ntb_plx_link_enable), + DEVMETHOD(ntb_link_disable, ntb_plx_link_disable), + DEVMETHOD(ntb_link_enabled, ntb_plx_link_enabled), + DEVMETHOD(ntb_mw_count, ntb_plx_mw_count), + DEVMETHOD(ntb_mw_get_range, ntb_plx_mw_get_range), + DEVMETHOD(ntb_mw_set_trans, ntb_plx_mw_set_trans), + DEVMETHOD(ntb_mw_clear_trans, ntb_plx_mw_clear_trans), + DEVMETHOD(ntb_mw_get_wc, ntb_plx_mw_get_wc), + DEVMETHOD(ntb_mw_set_wc, ntb_plx_mw_set_wc), + DEVMETHOD(ntb_spad_count, ntb_plx_spad_count), + DEVMETHOD(ntb_spad_clear, ntb_plx_spad_clear), + DEVMETHOD(ntb_spad_write, ntb_plx_spad_write), + DEVMETHOD(ntb_spad_read, ntb_plx_spad_read), + DEVMETHOD(ntb_peer_spad_write, ntb_plx_peer_spad_write), + DEVMETHOD(ntb_peer_spad_read, ntb_plx_peer_spad_read), + DEVMETHOD(ntb_db_valid_mask, ntb_plx_db_valid_mask), + DEVMETHOD(ntb_db_vector_count, ntb_plx_db_vector_count), + DEVMETHOD(ntb_db_vector_mask, ntb_plx_db_vector_mask), + DEVMETHOD(ntb_db_clear, ntb_plx_db_clear), + DEVMETHOD(ntb_db_clear_mask, ntb_plx_db_clear_mask), + DEVMETHOD(ntb_db_read, ntb_plx_db_read), + DEVMETHOD(ntb_db_set_mask, ntb_plx_db_set_mask), + DEVMETHOD(ntb_peer_db_addr, ntb_plx_peer_db_addr), + DEVMETHOD(ntb_peer_db_set, ntb_plx_peer_db_set), + DEVMETHOD_END +}; + +static DEFINE_CLASS_0(ntb_hw, ntb_plx_driver, ntb_plx_methods, + sizeof(struct ntb_plx_softc)); +DRIVER_MODULE(ntb_hw_plx, pci, ntb_plx_driver, ntb_hw_devclass, NULL, NULL); +MODULE_DEPEND(ntb_hw_plx, ntb, 1, 1, 1); +MODULE_VERSION(ntb_hw_plx, 1); Property changes on: stable/11/sys/dev/ntb/ntb_hw/ntb_hw_plx.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11/sys/i386/conf/NOTES =================================================================== --- stable/11/sys/i386/conf/NOTES (revision 323452) +++ stable/11/sys/i386/conf/NOTES (revision 323453) @@ -1,1071 +1,1080 @@ # # NOTES -- Lines that can be cut/pasted into kernel and hints configs. # # This file contains machine dependent kernel configuration notes. For # machine independent notes, look in /sys/conf/NOTES. # # $FreeBSD$ # # # We want LINT to cover profiling as well. profile 2 # # Enable the kernel DTrace hooks which are required to load the DTrace # kernel modules. # options KDTRACE_HOOKS # DTrace core # NOTE: introduces CDDL-licensed components into the kernel #device dtrace # DTrace modules #device dtrace_profile #device dtrace_sdt #device dtrace_fbt #device dtrace_systrace #device dtrace_prototype #device dtnfscl #device dtmalloc # Alternatively include all the DTrace modules #device dtraceall ##################################################################### # SMP OPTIONS: # # The apic device enables the use of the I/O APIC for interrupt delivery. # The apic device can be used in both UP and SMP kernels, but is required # for SMP kernels. Thus, the apic device is not strictly an SMP option, # but it is a prerequisite for SMP. # # Notes: # # HTT CPUs should only be used if they are enabled in the BIOS. For # the ACPI case, ACPI only correctly tells us about any HTT CPUs if # they are enabled. However, most HTT systems do not list HTT CPUs # in the MP Table if they are enabled, thus we guess at the HTT CPUs # for the MP Table case. However, we shouldn't try to guess and use # these CPUs if HTT is disabled. Thus, HTT guessing is only enabled # for the MP Table if the user explicitly asks for it via the # MPTABLE_FORCE_HTT option. Do NOT use this option if you have HTT # disabled in your BIOS. # # IPI_PREEMPTION instructs the kernel to preempt threads running on other # CPUS if needed. Relies on the PREEMPTION option # Mandatory: device apic # I/O apic # Optional: options MPTABLE_FORCE_HTT # Enable HTT CPUs with the MP Table options IPI_PREEMPTION # # Watchdog routines. # options MP_WATCHDOG # Debugging options. # options COUNT_XINVLTLB_HITS # Counters for TLB events options COUNT_IPIS # Per-CPU IPI interrupt counters ##################################################################### # CPU OPTIONS # # You must specify at least one CPU (the one you intend to run on); # deleting the specification for CPUs you don't need to use may make # parts of the system run faster. # cpu I486_CPU cpu I586_CPU # aka Pentium(tm) cpu I686_CPU # aka Pentium Pro(tm) # # Options for CPU features. # # CPU_ATHLON_SSE_HACK tries to enable SSE instructions when the BIOS has # forgotten to enable them. # # CPU_BLUELIGHTNING_3X enables triple-clock mode on IBM Blue Lightning # CPU if CPU supports it. The default is double-clock mode on # BlueLightning CPU box. # # CPU_BLUELIGHTNING_FPU_OP_CACHE enables FPU operand cache on IBM # BlueLightning CPU. It works only with Cyrix FPU, and this option # should not be used with Intel FPU. # # CPU_BTB_EN enables branch target buffer on Cyrix 5x86 (NOTE 1). # # CPU_CYRIX_NO_LOCK enables weak locking for the entire address space # of Cyrix 6x86 and 6x86MX CPUs by setting the NO_LOCK bit of CCR1. # Otherwise, the NO_LOCK bit of CCR1 is cleared. (NOTE 3) # # CPU_DIRECT_MAPPED_CACHE sets L1 cache of Cyrix 486DLC CPU in direct # mapped mode. Default is 2-way set associative mode. # # CPU_DISABLE_5X86_LSSER disables load store serialize (i.e., enables # reorder). This option should not be used if you use memory mapped # I/O device(s). # # CPU_ELAN enables support for AMDs ElanSC520 CPU. # CPU_ELAN_PPS enables precision timestamp code. # CPU_ELAN_XTAL sets the clock crystal frequency in Hz. # # CPU_ENABLE_LONGRUN enables support for Transmeta Crusoe LongRun # technology which allows to restrict power consumption of the CPU by # using group of hw.crusoe.* sysctls. # # CPU_FASTER_5X86_FPU enables faster FPU exception handler. # # CPU_GEODE is for the SC1100 Geode embedded processor. This option # is necessary because the i8254 timecounter is toast. # # CPU_I486_ON_386 enables CPU cache on i486 based CPU upgrade products # for i386 machines. # # CPU_IORT defines I/O clock delay time (NOTE 1). Default values of # I/O clock delay time on Cyrix 5x86 and 6x86 are 0 and 7,respectively # (no clock delay). # # CPU_L2_LATENCY specifies the L2 cache latency value. This option is used # only when CPU_PPRO2CELERON is defined and Mendocino Celeron is detected. # The default value is 5. # # CPU_LOOP_EN prevents flushing the prefetch buffer if the destination # of a jump is already present in the prefetch buffer on Cyrix 5x86(NOTE # 1). # # CPU_PPRO2CELERON enables L2 cache of Mendocino Celeron CPUs. This option # is useful when you use Socket 8 to Socket 370 converter, because most Pentium # Pro BIOSs do not enable L2 cache of Mendocino Celeron CPUs. # # CPU_RSTK_EN enables return stack on Cyrix 5x86 (NOTE 1). # # CPU_SOEKRIS enables support www.soekris.com hardware. # # CPU_SUSP_HLT enables suspend on HALT. If this option is set, CPU # enters suspend mode following execution of HALT instruction. # # CPU_UPGRADE_HW_CACHE eliminates unneeded cache flush instruction(s). # # CPU_WT_ALLOC enables write allocation on Cyrix 6x86/6x86MX and AMD # K5/K6/K6-2 CPUs. # # CYRIX_CACHE_WORKS enables CPU cache on Cyrix 486 CPUs with cache # flush at hold state. # # CYRIX_CACHE_REALLY_WORKS enables (1) CPU cache on Cyrix 486 CPUs # without cache flush at hold state, and (2) write-back CPU cache on # Cyrix 6x86 whose revision < 2.7 (NOTE 2). # # NO_F00F_HACK disables the hack that prevents Pentiums (and ONLY # Pentiums) from locking up when a LOCK CMPXCHG8B instruction is # executed. This option is only needed if I586_CPU is also defined, # and should be included for any non-Pentium CPU that defines it. # # NO_MEMORY_HOLE is an optimisation for systems with AMD K6 processors # which indicates that the 15-16MB range is *definitely* not being # occupied by an ISA memory hole. # # NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT, # CPU_LOOP_EN and CPU_RSTK_EN should not be used because of CPU bugs. # These options may crash your system. # # NOTE 2: If CYRIX_CACHE_REALLY_WORKS is not set, CPU cache is enabled # in write-through mode when revision < 2.7. If revision of Cyrix # 6x86 >= 2.7, CPU cache is always enabled in write-back mode. # # NOTE 3: This option may cause failures for software that requires # locked cycles in order to operate correctly. # options CPU_ATHLON_SSE_HACK options CPU_BLUELIGHTNING_3X options CPU_BLUELIGHTNING_FPU_OP_CACHE options CPU_BTB_EN options CPU_DIRECT_MAPPED_CACHE options CPU_DISABLE_5X86_LSSER options CPU_ELAN options CPU_ELAN_PPS options CPU_ELAN_XTAL=32768000 options CPU_ENABLE_LONGRUN options CPU_FASTER_5X86_FPU options CPU_GEODE options CPU_I486_ON_386 options CPU_IORT options CPU_L2_LATENCY=5 options CPU_LOOP_EN options CPU_PPRO2CELERON options CPU_RSTK_EN options CPU_SOEKRIS options CPU_SUSP_HLT options CPU_UPGRADE_HW_CACHE options CPU_WT_ALLOC options CYRIX_CACHE_WORKS options CYRIX_CACHE_REALLY_WORKS #options NO_F00F_HACK # Debug options options NPX_DEBUG # enable npx debugging # # PERFMON causes the driver for Pentium/Pentium Pro performance counters # to be compiled. See perfmon(4) for more information. # options PERFMON # # XBOX causes the kernel to be bootable on the Microsoft XBox console system. # The resulting kernel will auto-detect whether it is being booted on a XBox, # so kernels compiled with this option will also work on an ordinary PC. # This option require I686_CPU. # # xboxfb includes support for the XBox frame buffer device. It is fully USB- # keyboard aware, and will only be used if an xbox is detected. This option # (obviously) requires XBOX support in your kernel. # # NOTE: xboxfb currently conflicts with syscons(4); if you have an XBOX and # include both in your kernel; you will not get any video output. Ordinary # PC's do not suffer from this. # options XBOX device xboxfb ##################################################################### # NETWORKING OPTIONS # # DEVICE_POLLING adds support for mixed interrupt-polling handling # of network device drivers, which has significant benefits in terms # of robustness to overloads and responsivity, as well as permitting # accurate scheduling of the CPU time between kernel network processing # and other activities. The drawback is a moderate (up to 1/HZ seconds) # potential increase in response times. # It is strongly recommended to use HZ=1000 or 2000 with DEVICE_POLLING # to achieve smoother behaviour. # Additionally, you can enable/disable polling at runtime with help of # the ifconfig(8) utility, and select the CPU fraction reserved to # userland with the sysctl variable kern.polling.user_frac # (default 50, range 0..100). # # Not all device drivers support this mode of operation at the time of # this writing. See polling(4) for more details. options DEVICE_POLLING # BPF_JITTER adds support for BPF just-in-time compiler. options BPF_JITTER # OpenFabrics Enterprise Distribution (Infiniband). options OFED options OFED_DEBUG_INIT # Sockets Direct Protocol options SDP options SDP_DEBUG # IP over Infiniband options IPOIB options IPOIB_DEBUG options IPOIB_CM ##################################################################### # CLOCK OPTIONS # Provide read/write access to the memory in the clock chip. device nvram # Access to rtc cmos via /dev/nvram ##################################################################### # MISCELLANEOUS DEVICES AND OPTIONS device speaker #Play IBM BASIC-style noises out your speaker hint.speaker.0.at="isa" hint.speaker.0.port="0x61" device gzip #Exec gzipped a.out's. REQUIRES COMPAT_AOUT! device apm_saver # Requires APM ##################################################################### # HARDWARE BUS CONFIGURATION # # ISA bus # device isa # # Options for `isa': # # AUTO_EOI_1 enables the `automatic EOI' feature for the master 8259A # interrupt controller. This saves about 0.7-1.25 usec for each interrupt. # This option breaks suspend/resume on some portables. # # AUTO_EOI_2 enables the `automatic EOI' feature for the slave 8259A # interrupt controller. This saves about 0.7-1.25 usec for each interrupt. # Automatic EOI is documented not to work for for the slave with the # original i8259A, but it works for some clones and some integrated # versions. # # MAXMEM specifies the amount of RAM on the machine; if this is not # specified, FreeBSD will first read the amount of memory from the CMOS # RAM, so the amount of memory will initially be limited to 64MB or 16MB # depending on the BIOS. If the BIOS reports 64MB, a memory probe will # then attempt to detect the installed amount of RAM. If this probe # fails to detect >64MB RAM you will have to use the MAXMEM option. # The amount is in kilobytes, so for a machine with 128MB of RAM, it would # be 131072 (128 * 1024). # # BROKEN_KEYBOARD_RESET disables the use of the keyboard controller to # reset the CPU for reboot. This is needed on some systems with broken # keyboard controllers. options AUTO_EOI_1 #options AUTO_EOI_2 options MAXMEM=(128*1024) #options BROKEN_KEYBOARD_RESET # # EISA bus # # The EISA bus device is `eisa'. It provides auto-detection and # configuration support for all devices on the EISA bus. device eisa # By default, only 10 EISA slots are probed, since the slot numbers # above clash with the configuration address space of the PCI subsystem, # and the EISA probe is not very smart about this. This is sufficient # for most machines, but in particular the HP NetServer LC series comes # with an onboard AIC7770 dual-channel SCSI controller on EISA slot #11, # thus you need to bump this figure to 12 for them. options EISA_SLOTS=12 # # MCA bus: # # The MCA bus device is `mca'. It provides auto-detection and # configuration support for all devices on the MCA bus. # No hints are required for MCA. device mca # # AGP GART support device agp # AGP debugging. options AGP_DEBUG ##################################################################### # HARDWARE DEVICE CONFIGURATION # To include support for VGA VESA video modes options VESA # Turn on extra debugging checks and output for VESA support. options VESA_DEBUG device dpms # DPMS suspend & resume via VESA BIOS # x86 real mode BIOS emulator, required by atkbdc/dpms/vesa options X86BIOS # # Hints for the non-optional Numeric Processing eXtension driver. hint.npx.0.flags="0x0" hint.npx.0.irq="13" # # `flags' for npx0: # 0x01 don't use the npx registers to optimize bcopy. # 0x02 don't use the npx registers to optimize bzero. # 0x04 don't use the npx registers to optimize copyin or copyout. # The npx registers are normally used to optimize copying and zeroing when # all of the following conditions are satisfied: # I586_CPU is an option # the cpu is an i586 (perhaps not a Pentium) # the probe for npx0 succeeds # INT 16 exception handling works. # Then copying and zeroing using the npx registers is normally 30-100% faster. # The flags can be used to control cases where it doesn't work or is slower. # Setting them at boot time using hints works right (the optimizations # are not used until later in the bootstrap when npx0 is attached). # Flag 0x08 automatically disables the i586 optimized routines. # # # Optional devices: # # PS/2 mouse device psm hint.psm.0.at="atkbdc" hint.psm.0.irq="12" # Options for psm: options PSM_HOOKRESUME #hook the system resume event, useful #for some laptops options PSM_RESETAFTERSUSPEND #reset the device at the resume event # The keyboard controller; it controls the keyboard and the PS/2 mouse. device atkbdc hint.atkbdc.0.at="isa" hint.atkbdc.0.port="0x060" # The AT keyboard device atkbd hint.atkbd.0.at="atkbdc" hint.atkbd.0.irq="1" # Options for atkbd: options ATKBD_DFLT_KEYMAP # specify the built-in keymap makeoptions ATKBD_DFLT_KEYMAP=fr.dvorak # `flags' for atkbd: # 0x01 Force detection of keyboard, else we always assume a keyboard # 0x02 Don't reset keyboard, useful for some newer ThinkPads # 0x03 Force detection and avoid reset, might help with certain # dockingstations # 0x04 Old-style (XT) keyboard support, useful for older ThinkPads # Video card driver for VGA adapters. device vga hint.vga.0.at="isa" # Options for vga: # Try the following option if the mouse pointer is not drawn correctly # or font does not seem to be loaded properly. May cause flicker on # some systems. options VGA_ALT_SEQACCESS # If you can dispense with some vga driver features, you may want to # use the following options to save some memory. #options VGA_NO_FONT_LOADING # don't save/load font #options VGA_NO_MODE_CHANGE # don't change video modes # Older video cards may require this option for proper operation. options VGA_SLOW_IOACCESS # do byte-wide i/o's to TS and GDC regs # The following option probably won't work with the LCD displays. options VGA_WIDTH90 # support 90 column modes # Debugging. options VGA_DEBUG # vt(4) drivers. device vt_vga # Linear framebuffer driver for S3 VESA 1.2 cards. Works on top of VESA. device s3pci # 3Dfx Voodoo Graphics, Voodoo II /dev/3dfx CDEV support. This will create # the /dev/3dfx0 device to work with glide implementations. This should get # linked to /dev/3dfx and /dev/voodoo. Note that this is not the same as # the tdfx DRI module from XFree86 and is completely unrelated. # # To enable Linuxulator support, one must also include COMPAT_LINUX in the # config as well. The other option is to load both as modules. device tdfx # Enable 3Dfx Voodoo support device tdfx_linux # Enable Linuxulator support # # ACPI support using the Intel ACPI Component Architecture reference # implementation. # # ACPI_DEBUG enables the use of the debug.acpi.level and debug.acpi.layer # kernel environment variables to select initial debugging levels for the # Intel ACPICA code. (Note that the Intel code must also have USE_DEBUGGER # defined when it is built). device acpi options ACPI_DEBUG options ACPI_DMAR # ACPI WMI Mapping driver device acpi_wmi # ACPI Asus Extras (LCD backlight/brightness, video output, etc.) device acpi_asus # ACPI Fujitsu Extras (Buttons) device acpi_fujitsu # ACPI extras driver for HP laptops device acpi_hp # ACPI extras driver for IBM laptops device acpi_ibm # ACPI Panasonic Extras (LCD backlight/brightness, video output, etc.) device acpi_panasonic # ACPI Sony extra (LCD brightness) device acpi_sony # ACPI Toshiba Extras (LCD backlight/brightness, video output, etc.) device acpi_toshiba # ACPI Video Extensions (LCD backlight/brightness, video output, etc.) device acpi_video # ACPI Docking Station device acpi_dock # ACPI ASOC ATK0110 ASUSTeK AI Booster (voltage, temperature and fan sensors) device aibs # The cpufreq(4) driver provides support for non-ACPI CPU frequency control device cpufreq # Direct Rendering modules for 3D acceleration. device drm # DRM core module required by DRM drivers device i915drm # Intel i830 through i915 device mach64drm # ATI Rage Pro, Rage Mobility P/M, Rage XL device mgadrm # AGP Matrox G200, G400, G450, G550 device r128drm # ATI Rage 128 device radeondrm # ATI Radeon device savagedrm # S3 Savage3D, Savage4 device sisdrm # SiS 300/305, 540, 630 device tdfxdrm # 3dfx Voodoo 3/4/5 and Banshee device viadrm # VIA options DRM_DEBUG # Include debug printfs (slow) # # mse: Logitech and ATI InPort bus mouse ports device mse hint.mse.0.at="isa" hint.mse.0.port="0x23c" hint.mse.0.irq="5" # # Network interfaces: # # bxe: Broadcom NetXtreme II (BCM5771X/BCM578XX) PCIe 10Gb Ethernet # adapters. # ce: Cronyx Tau-PCI/32 sync single/dual port G.703/E1 serial adaptor # with 32 HDLC subchannels (requires sppp (default), or NETGRAPH if # NETGRAPH_CRONYX is configured) # cp: Cronyx Tau-PCI sync single/dual/four port # V.35/RS-232/RS-530/RS-449/X.21/G.703/E1/E3/T3/STS-1 # serial adaptor (requires sppp (default), or NETGRAPH if # NETGRAPH_CRONYX is configured) # cs: IBM Etherjet and other Crystal Semi CS89x0-based adapters # ctau: Cronyx Tau sync dual port V.35/RS-232/RS-530/RS-449/X.21/G.703/E1 # serial adaptor (requires sppp (default), or NETGRAPH if # NETGRAPH_CRONYX is configured) # ed: Western Digital and SMC 80xx; Novell NE1000 and NE2000; 3Com 3C503 # HP PC Lan+, various PC Card devices # (requires miibus) # ie: AT&T StarLAN 10 and EN100; 3Com 3C507; unknown NI5210; # Intel EtherExpress # ipw: Intel PRO/Wireless 2100 IEEE 802.11 adapter # iwi: Intel PRO/Wireless 2200BG/2225BG/2915ABG IEEE 802.11 adapters # Requires the iwi firmware module # iwn: Intel Wireless WiFi Link 1000/105/135/2000/4965/5000/6000/6050 abgn # 802.11 network adapters # Requires the iwn firmware module # mlx4ib: Mellanox ConnectX HCA InfiniBand # mlxen: Mellanox ConnectX HCA Ethernet # mthca: Mellanox HCA InfiniBand # nfe: nVidia nForce MCP on-board Ethernet Networking (BSD open source) # sbni: Granch SBNI12-xx ISA and PCI adapters # vmx: VMware VMXNET3 Ethernet (BSD open source) # wl: Lucent Wavelan (ISA card only). # wpi: Intel 3945ABG Wireless LAN controller # Requires the wpi firmware module # Order for ISA/EISA devices is important here device bxe # Broadcom NetXtreme II BCM5771X/BCM578XX 10GbE device ce device cp device cs # Crystal Semiconductor CS89x0 NIC hint.cs.0.at="isa" hint.cs.0.port="0x300" device ctau hint.ctau.0.at="isa" hint.ctau.0.port="0x240" hint.ctau.0.irq="15" hint.ctau.0.drq="7" #options NETGRAPH_CRONYX # Enable NETGRAPH support for Cronyx adapter(s) device ed # NE[12]000, SMC Ultra, 3c503, DS8390 cards options ED_3C503 options ED_HPP options ED_SIC hint.ed.0.at="isa" hint.ed.0.port="0x280" hint.ed.0.irq="5" hint.ed.0.maddr="0xd8000" device ie # EtherExpress 8/16, 3C507, StarLAN 10 etc. # Hints only required for Starlan hint.ie.2.at="isa" hint.ie.2.port="0x300" hint.ie.2.irq="5" hint.ie.2.maddr="0xd0000" device ipw # Intel 2100 wireless NICs. device iwi # Intel 2200BG/2225BG/2915ABG wireless NICs. device iwn # Intel 4965/1000/5000/6000 wireless NICs. # Hint for the i386-only ISA front-end of le(4). hint.le.0.at="isa" hint.le.0.port="0x280" hint.le.0.irq="10" hint.le.0.drq="0" device mlx4ib # Mellanox ConnectX HCA InfiniBand device mlxen # Mellanox ConnectX HCA Ethernet device mthca # Mellanox HCA InfiniBand device nfe # nVidia nForce MCP on-board Ethernet device sbni hint.sbni.0.at="isa" hint.sbni.0.port="0x210" hint.sbni.0.irq="0xefdead" hint.sbni.0.flags="0" device vmx # VMware VMXNET3 Ethernet device wl hint.wl.0.at="isa" hint.wl.0.port="0x300" options WLCACHE # enables the signal-strength cache options WLDEBUG # enables verbose debugging output device wpi # Intel 3945ABG wireless NICs. # IEEE 802.11 adapter firmware modules # Intel PRO/Wireless 2100 firmware: # ipwfw: BSS/IBSS/monitor mode firmware # ipwbssfw: BSS mode firmware # ipwibssfw: IBSS mode firmware # ipwmonitorfw: Monitor mode firmware # Intel PRO/Wireless 2200BG/2225BG/2915ABG firmware: # iwifw: BSS/IBSS/monitor mode firmware # iwibssfw: BSS mode firmware # iwiibssfw: IBSS mode firmware # iwimonitorfw: Monitor mode firmware # Intel Wireless WiFi Link 4965/1000/5000/6000 series firmware: # iwnfw: Single module to support all devices # iwn1000fw: Specific module for the 1000 only # iwn105fw: Specific module for the 105 only # iwn135fw: Specific module for the 135 only # iwn2000fw: Specific module for the 2000 only # iwn2030fw: Specific module for the 2030 only # iwn4965fw: Specific module for the 4965 only # iwn5000fw: Specific module for the 5000 only # iwn5150fw: Specific module for the 5150 only # iwn6000fw: Specific module for the 6000 only # iwn6000g2afw: Specific module for the 6000g2a only # iwn6000g2bfw: Specific module for the 6000g2b only # iwn6050fw: Specific module for the 6050 only # wpifw: Intel 3945ABG Wireless LAN Controller firmware device iwifw device iwibssfw device iwiibssfw device iwimonitorfw device ipwfw device ipwbssfw device ipwibssfw device ipwmonitorfw device iwnfw device iwn1000fw device iwn105fw device iwn135fw device iwn2000fw device iwn2030fw device iwn4965fw device iwn5000fw device iwn5150fw device iwn6000fw device iwn6000g2afw device iwn6000g2bfw device iwn6050fw device wpifw # +# Non-Transparent Bridge (NTB) drivers +# +device if_ntb # Virtual NTB network interface +device ntb_transport # NTB packet transport driver +device ntb # NTB hardware interface +device ntb_hw_intel # Intel NTB hardware driver +device ntb_hw_plx # PLX NTB hardware driver + +# # ATA raid adapters # device pst # # Areca 11xx and 12xx series of SATA II RAID controllers. # CAM is required. # device arcmsr # Areca SATA II RAID # # 3ware 9000 series PATA/SATA RAID controller driver and options. # The driver is implemented as a SIM, and so, needs the CAM infrastructure. # options TWA_DEBUG # 0-10; 10 prints the most messages. options TWA_FLASH_FIRMWARE # firmware image bundled when defined. device twa # 3ware 9000 series PATA/SATA RAID # # SCSI host adapters: # # ncv: NCR 53C500 based SCSI host adapters. # nsp: Workbit Ninja SCSI-3 based PC Card SCSI host adapters. # stg: TMC 18C30, 18C50 based SCSI host adapters. device ncv device nsp device stg hint.stg.0.at="isa" hint.stg.0.port="0x140" hint.stg.0.port="11" # # Adaptec FSA RAID controllers, including integrated DELL controllers, # the Dell PERC 2/QC and the HP NetRAID-4M device aac device aacp # SCSI Passthrough interface (optional, CAM required) # # Adaptec by PMC RAID controllers, Series 6/7/8 and upcoming families device aacraid # Container interface, CAM required # # Highpoint RocketRAID 27xx. device hpt27xx # # Highpoint RocketRAID 182x. device hptmv # # Highpoint DC7280 and R750. device hptnr # # Highpoint RocketRAID. Supports RR172x, RR222x, RR2240, RR232x, RR2340, # RR2210, RR174x, RR2522, RR231x, RR230x. device hptrr # # Highpoint RocketRaid 3xxx series SATA RAID device hptiop # # IBM (now Adaptec) ServeRAID controllers device ips # # Intel C600 (Patsburg) integrated SAS controller device isci options ISCI_LOGGING # enable debugging in isci HAL # # NVM Express (NVMe) support device nvme # base NVMe driver device nvd # expose NVMe namespaces as disks, depends on nvme # # PMC-Sierra SAS/SATA controller device pmspcv # # SafeNet crypto driver: can be moved to the MI NOTES as soon as # it's tested on a big-endian machine # device safe # SafeNet 1141 options SAFE_DEBUG # enable debugging support: hw.safe.debug options SAFE_RNDTEST # enable rndtest support # # glxiic is an I2C driver for the AMD Geode LX CS5536 System Management Bus # controller. Requires 'device iicbus'. # device glxiic # AMD Geode LX CS5536 System Management Bus # # glxsb is a driver for the Security Block in AMD Geode LX processors. # Requires 'device crypto'. # device glxsb # AMD Geode LX Security Block # # VirtIO support # # The virtio entry provides a generic bus for use by the device drivers. # It must be combined with an interface that communicates with the host. # Multiple such interfaces defined by the VirtIO specification. FreeBSD # only has support for PCI. Therefore, virtio_pci must be statically # compiled in or loaded as a module for the device drivers to function. # device virtio # Generic VirtIO bus (required) device virtio_pci # VirtIO PCI Interface device vtnet # VirtIO Ethernet device device virtio_blk # VirtIO Block device device virtio_scsi # VirtIO SCSI device device virtio_balloon # VirtIO Memory Balloon device device virtio_random # VirtIO Entropy device device virtio_console # VirtIO Console device device hyperv # HyperV drivers ##################################################################### # # Miscellaneous hardware: # # apm: Laptop Advanced Power Management (experimental) # ipmi: Intelligent Platform Management Interface # smapi: System Management Application Program Interface driver # smbios: DMI/SMBIOS entry point # vpd: Vital Product Data kernel interface # pmtimer: Adjust system timer at wakeup time # pbio: Parallel (8255 PPI) basic I/O (mode 0) port (e.g. Advantech PCL-724) # spic: Sony Programmable I/O controller (VAIO notebooks) # asmc: Apple System Management Controller # si: Specialix International SI/XIO or SX intelligent serial card driver # tpm: Trusted Platform Module # Notes on APM # The flags takes the following meaning for apm0: # 0x0020 Statclock is broken. # Notes on the Specialix SI/XIO driver: # The host card is memory, not IO mapped. # The Rev 1 host cards use a 64K chunk, on a 32K boundary. # The Rev 2 host cards use a 32K chunk, on a 32K boundary. # The cards can use an IRQ of 11, 12 or 15. # Notes on the Sony Programmable I/O controller # This is a temporary driver that should someday be replaced by something # that hooks into the ACPI layer. The device is hooked to the PIIX4's # General Device 10 decoder, which means you have to fiddle with PCI # registers to map it in, even though it is otherwise treated here as # an ISA device. At the moment, the driver polls, although the device # is capable of generating interrupts. It largely undocumented. # The port location in the hint is where you WANT the device to be # mapped. 0x10a0 seems to be traditional. At the moment the jogdial # is the only thing truly supported, but apparently a fair percentage # of the Vaio extra features are controlled by this device. device apm hint.apm.0.flags="0x20" device ipmi device smapi device smbios device vpd device pmtimer device pbio hint.pbio.0.at="isa" hint.pbio.0.port="0x360" device spic hint.spic.0.at="isa" hint.spic.0.port="0x10a0" device asmc device si device tpm device padlock_rng # VIA Padlock RNG device rdrand_rng # Intel Bull Mountain RNG device aesni # AES-NI OpenCrypto module # # Laptop/Notebook options: # # See also: # apm under `Miscellaneous hardware' # above. # For older notebooks that signal a powerfail condition (external # power supply dropped, or battery state low) by issuing an NMI: options POWERFAIL_NMI # make it beep instead of panicing # # I2C Bus # # Philips i2c bus support is provided by the `iicbus' device. # # Supported interfaces: # pcf Philips PCF8584 ISA-bus controller # device pcf hint.pcf.0.at="isa" hint.pcf.0.port="0x320" hint.pcf.0.irq="5" # # Hardware watchdog timers: # # ichwd: Intel ICH watchdog timer # amdsbwd: AMD SB7xx watchdog timer # viawd: VIA south bridge watchdog timer # wbwd: Winbond watchdog timer # device ichwd device amdsbwd device viawd device wbwd # # Temperature sensors: # # coretemp: on-die sensor on Intel Core and newer CPUs # amdtemp: on-die sensor on AMD K8/K10/K11 CPUs # device coretemp device amdtemp # # CPU control pseudo-device. Provides access to MSRs, CPUID info and # microcode update feature. # device cpuctl # # System Management Bus (SMB) # options ENABLE_ALART # Control alarm on Intel intpm driver # # Set the number of PV entries per process. Increasing this can # stop panics related to heavy use of shared memory. However, that can # (combined with large amounts of physical memory) cause panics at # boot time due the kernel running out of VM space. # # If you're tweaking this, you might also want to increase the sysctls # "vm.v_free_min", "vm.v_free_reserved", and "vm.v_free_target". # # The value below is the one more than the default. # options PMAP_SHPGPERPROC=201 # # Change the size of the kernel virtual address space. Due to # constraints in loader(8) on i386, this must be a multiple of 4. # 256 = 1 GB of kernel address space. Increasing this also causes # a reduction of the address space in user processes. 512 splits # the 4GB cpu address space in half (2GB user, 2GB kernel). For PAE # kernels, the value will need to be double non-PAE. A value of 1024 # for PAE kernels is necessary to split the address space in half. # This will likely need to be increased to handle memory sizes >4GB. # PAE kernels default to a value of 512. # options KVA_PAGES=260 # # Number of initial kernel page table pages used for early bootstrap. # This number should include enough pages to map the kernel, any # modules or other data loaded with the kernel by the loader, and data # structures allocated before the VM system is initialized such as the # vm_page_t array. Each page table page maps 4MB (2MB with PAE). # options NKPT=31 ##################################################################### # ABI Emulation # Enable iBCS2 runtime support for SCO and ISC binaries #options IBCS2 # Emulate spx device for client side of SVR3 local X interface options SPX_HACK # Enable 32-bit runtime support for CloudABI binaries. options COMPAT_CLOUDABI32 # Enable Linux ABI emulation options COMPAT_LINUX # Enable i386 a.out binary support options COMPAT_AOUT # Enable the linux-like proc filesystem support (requires COMPAT_LINUX # and PSEUDOFS) options LINPROCFS #Enable the linux-like sys filesystem support (requires COMPAT_LINUX # and PSEUDOFS) options LINSYSFS # # SysVR4 ABI emulation # # The svr4 ABI emulator can be statically compiled into the kernel or loaded as # a KLD module. # The STREAMS network emulation code can also be compiled statically or as a # module. If loaded as a module, it must be loaded before the svr4 module # (the /usr/sbin/svr4 script does this for you). If compiling statically, # the `streams' device must be configured into any kernel which also # specifies COMPAT_SVR4. It is possible to have a statically-configured # STREAMS device and a dynamically loadable svr4 emulator; the /usr/sbin/svr4 # script understands that it doesn't need to load the `streams' module under # those circumstances. # Caveat: At this time, `options KTRACE' is required for the svr4 emulator # (whether static or dynamic). # options COMPAT_SVR4 # build emulator statically options DEBUG_SVR4 # enable verbose debugging device streams # STREAMS network driver (required for svr4). # Enable NDIS binary driver support options NDISAPI device ndis ##################################################################### # VM OPTIONS # Disable the 4 MByte page PSE CPU feature. The PSE feature allows the # kernel to use 4 MByte pages to map the kernel instead of 4k pages. # This saves on the amount of memory needed for page tables needed to # map the kernel. You should only disable this feature as a temporary # workaround if you are having problems with it enabled. # #options DISABLE_PSE # Disable the global pages PGE CPU feature. The PGE feature allows pages # to be marked with the PG_G bit. TLB entries for these pages are not # flushed from the cache when %cr3 is reloaded. This can make context # switches less expensive. You should only disable this feature as a # temporary workaround if you are having problems with it enabled. # #options DISABLE_PG_G # KSTACK_PAGES is the number of memory pages to assign to the kernel # stack of each thread. options KSTACK_PAGES=3 # Enable detailed accounting by the PV entry allocator. options PV_STATS ##################################################################### # More undocumented options for linting. # Note that documenting these are not considered an affront. options FB_INSTALL_CDEV # install a CDEV entry in /dev options I586_PMC_GUPROF=0x70000 options KBDIO_DEBUG=2 options KBD_MAXRETRY=4 options KBD_MAXWAIT=6 options KBD_RESETDELAY=201 options PSM_DEBUG=1 options TIMER_FREQ=((14318182+6)/12) options VM_KMEM_SIZE options VM_KMEM_SIZE_MAX options VM_KMEM_SIZE_SCALE Index: stable/11/sys/modules/ntb/ntb_hw/Makefile =================================================================== --- stable/11/sys/modules/ntb/ntb_hw/Makefile (revision 323452) +++ stable/11/sys/modules/ntb/ntb_hw/Makefile (nonexistent) @@ -1,9 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/ntb/ntb_hw - -KMOD = ntb_hw -SRCS = ntb_hw.c -SRCS += device_if.h bus_if.h pci_if.h ntb_if.h - -.include Property changes on: stable/11/sys/modules/ntb/ntb_hw/Makefile ___________________________________________________________________ Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Index: stable/11/sys/modules/ntb/Makefile =================================================================== --- stable/11/sys/modules/ntb/Makefile (revision 323452) +++ stable/11/sys/modules/ntb/Makefile (revision 323453) @@ -1,5 +1,5 @@ # $FreeBSD$ -SUBDIR= ntb ntb_hw ntb_transport if_ntb +SUBDIR= ntb ntb_hw_intel ntb_hw_plx ntb_transport if_ntb .include Index: stable/11/sys/modules/ntb/ntb_hw_intel/Makefile =================================================================== --- stable/11/sys/modules/ntb/ntb_hw_intel/Makefile (nonexistent) +++ stable/11/sys/modules/ntb/ntb_hw_intel/Makefile (revision 323453) @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/dev/ntb/ntb_hw + +KMOD = ntb_hw_intel +SRCS = ntb_hw_intel.c +SRCS += device_if.h bus_if.h pci_if.h ntb_if.h + +.include Property changes on: stable/11/sys/modules/ntb/ntb_hw_intel/Makefile ___________________________________________________________________ Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: stable/11/sys/modules/ntb/ntb_hw_plx/Makefile =================================================================== --- stable/11/sys/modules/ntb/ntb_hw_plx/Makefile (nonexistent) +++ stable/11/sys/modules/ntb/ntb_hw_plx/Makefile (revision 323453) @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${SRCTOP}/sys/dev/ntb/ntb_hw + +KMOD = ntb_hw_plx +SRCS = ntb_hw_plx.c +SRCS += device_if.h bus_if.h pci_if.h ntb_if.h + +.include Property changes on: stable/11/sys/modules/ntb/ntb_hw_plx/Makefile ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/11 =================================================================== --- stable/11 (revision 323452) +++ stable/11 (revision 323453) Property changes on: stable/11 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r323032,323053,323058-323059,323084,323114,323127