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:
parent
3062870897
commit
57ba792a67
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=291031
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user