ntb_hw: Add programmatic interface to enable/disable WC

Enable users to enable/disable WC on memory windows programmatically.

Sponsored by:	EMC / Isilon Storage Division
This commit is contained in:
Conrad Meyer 2015-11-18 22:20:21 +00:00
parent 3062870897
commit 57ba792a67
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=291031
2 changed files with 61 additions and 2 deletions

View File

@ -113,6 +113,7 @@ struct ntb_pci_bar_info {
vm_paddr_t pbase;
caddr_t vbase;
vm_size_t size;
bool mapped_wc : 1;
/* Configuration register offsets */
uint32_t psz_off;
@ -777,14 +778,15 @@ map_memory_window_bar(struct ntb_softc *ntb, struct ntb_pci_bar_info *bar)
/* Mark bar region as write combining to improve performance. */
rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size,
VM_MEMATTR_WRITE_COMBINING);
if (rc == 0)
if (rc == 0) {
bar->mapped_wc = true;
device_printf(ntb->device,
"Marked BAR%d v:[%p-%p] p:[%p-%p] as "
"WRITE_COMBINING.\n",
PCI_RID2BAR(bar->pci_resource_id), bar->vbase,
(char *)bar->vbase + bar->size - 1,
(void *)bar->pbase, (void *)(bar->pbase + bar->size - 1));
else
} else
device_printf(ntb->device,
"Unable to mark BAR%d v:[%p-%p] p:[%p-%p] as "
"WRITE_COMBINING: %d\n",
@ -2629,6 +2631,60 @@ ntb_mw_clear_trans(struct ntb_softc *ntb, unsigned mw_idx)
return (ntb_mw_set_trans(ntb, mw_idx, 0, 0));
}
/*
* ntb_mw_get_wc - Get the write-combine status of a memory window
*
* Returns: Zero on success, setting *wc; otherwise an error number (e.g. if
* idx is an invalid memory window).
*/
int
ntb_mw_get_wc(struct ntb_softc *ntb, unsigned idx, bool *wc)
{
struct ntb_pci_bar_info *bar;
if (idx >= ntb_mw_count(ntb))
return (EINVAL);
bar = &ntb->bar_info[ntb_mw_to_bar(ntb, idx)];
*wc = bar->mapped_wc;
return (0);
}
/*
* ntb_mw_set_wc - Set the write-combine status of a memory window
*
* If 'wc' matches the current status, this does nothing and succeeds.
*
* Returns: Zero on success, setting the caching attribute on the virtual
* mapping of the BAR; otherwise an error number (e.g. if idx is an invalid
* memory window, or if changing the caching attribute fails).
*/
int
ntb_mw_set_wc(struct ntb_softc *ntb, unsigned idx, bool wc)
{
struct ntb_pci_bar_info *bar;
vm_memattr_t attr;
int rc;
if (idx >= ntb_mw_count(ntb))
return (EINVAL);
bar = &ntb->bar_info[ntb_mw_to_bar(ntb, idx)];
if (bar->mapped_wc == wc)
return (0);
if (wc)
attr = VM_MEMATTR_WRITE_COMBINING;
else
attr = VM_MEMATTR_DEFAULT;
rc = pmap_change_attr((vm_offset_t)bar->vbase, bar->size, attr);
if (rc == 0)
bar->mapped_wc = wc;
return (rc);
}
/**
* ntb_peer_db_set() - Set the doorbell on the secondary/external side
* @ntb: pointer to ntb_softc instance

View File

@ -81,6 +81,9 @@ int ntb_mw_get_range(struct ntb_softc *, unsigned mw_idx, vm_paddr_t *base,
int ntb_mw_set_trans(struct ntb_softc *, unsigned mw_idx, bus_addr_t, size_t);
int ntb_mw_clear_trans(struct ntb_softc *, unsigned mw_idx);
int ntb_mw_get_wc(struct ntb_softc *, unsigned mw_idx, bool *wc);
int ntb_mw_set_wc(struct ntb_softc *, unsigned mw_idx, bool wc);
uint8_t ntb_get_max_spads(struct ntb_softc *ntb);
int ntb_spad_write(struct ntb_softc *ntb, unsigned int idx, uint32_t val);
int ntb_spad_read(struct ntb_softc *ntb, unsigned int idx, uint32_t *val);