Commit 18b5b8a9 authored by Jiawen Wu's avatar Jiawen Wu Committed by David S. Miller

net: libwx: Configure Rx and Tx unit on hardware

Configure hardware for preparing to process packets. Including configure
receive and transmit unit of the MAC layer, and setup the specific rings.
Signed-off-by: default avatarJiawen Wu <jiawenwu@trustnetic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5d3ac705
...@@ -804,6 +804,37 @@ void wx_flush_sw_mac_table(struct wx *wx) ...@@ -804,6 +804,37 @@ void wx_flush_sw_mac_table(struct wx *wx)
} }
EXPORT_SYMBOL(wx_flush_sw_mac_table); EXPORT_SYMBOL(wx_flush_sw_mac_table);
static int wx_add_mac_filter(struct wx *wx, u8 *addr, u16 pool)
{
u32 i;
if (is_zero_ether_addr(addr))
return -EINVAL;
for (i = 0; i < wx->mac.num_rar_entries; i++) {
if (wx->mac_table[i].state & WX_MAC_STATE_IN_USE) {
if (ether_addr_equal(addr, wx->mac_table[i].addr)) {
if (wx->mac_table[i].pools != (1ULL << pool)) {
memcpy(wx->mac_table[i].addr, addr, ETH_ALEN);
wx->mac_table[i].pools |= (1ULL << pool);
wx_sync_mac_table(wx);
return i;
}
}
}
if (wx->mac_table[i].state & WX_MAC_STATE_IN_USE)
continue;
wx->mac_table[i].state |= (WX_MAC_STATE_MODIFIED |
WX_MAC_STATE_IN_USE);
memcpy(wx->mac_table[i].addr, addr, ETH_ALEN);
wx->mac_table[i].pools |= (1ULL << pool);
wx_sync_mac_table(wx);
return i;
}
return -ENOMEM;
}
static int wx_del_mac_filter(struct wx *wx, u8 *addr, u16 pool) static int wx_del_mac_filter(struct wx *wx, u8 *addr, u16 pool)
{ {
u32 i; u32 i;
...@@ -828,6 +859,184 @@ static int wx_del_mac_filter(struct wx *wx, u8 *addr, u16 pool) ...@@ -828,6 +859,184 @@ static int wx_del_mac_filter(struct wx *wx, u8 *addr, u16 pool)
return -ENOMEM; return -ENOMEM;
} }
static int wx_available_rars(struct wx *wx)
{
u32 i, count = 0;
for (i = 0; i < wx->mac.num_rar_entries; i++) {
if (wx->mac_table[i].state == 0)
count++;
}
return count;
}
/**
* wx_write_uc_addr_list - write unicast addresses to RAR table
* @netdev: network interface device structure
* @pool: index for mac table
*
* Writes unicast address list to the RAR table.
* Returns: -ENOMEM on failure/insufficient address space
* 0 on no addresses written
* X on writing X addresses to the RAR table
**/
static int wx_write_uc_addr_list(struct net_device *netdev, int pool)
{
struct wx *wx = netdev_priv(netdev);
int count = 0;
/* return ENOMEM indicating insufficient memory for addresses */
if (netdev_uc_count(netdev) > wx_available_rars(wx))
return -ENOMEM;
if (!netdev_uc_empty(netdev)) {
struct netdev_hw_addr *ha;
netdev_for_each_uc_addr(ha, netdev) {
wx_del_mac_filter(wx, ha->addr, pool);
wx_add_mac_filter(wx, ha->addr, pool);
count++;
}
}
return count;
}
/**
* wx_mta_vector - Determines bit-vector in multicast table to set
* @wx: pointer to private structure
* @mc_addr: the multicast address
*
* Extracts the 12 bits, from a multicast address, to determine which
* bit-vector to set in the multicast table. The hardware uses 12 bits, from
* incoming rx multicast addresses, to determine the bit-vector to check in
* the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
* by the MO field of the MCSTCTRL. The MO field is set during initialization
* to mc_filter_type.
**/
static u32 wx_mta_vector(struct wx *wx, u8 *mc_addr)
{
u32 vector = 0;
switch (wx->mac.mc_filter_type) {
case 0: /* use bits [47:36] of the address */
vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
break;
case 1: /* use bits [46:35] of the address */
vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
break;
case 2: /* use bits [45:34] of the address */
vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
break;
case 3: /* use bits [43:32] of the address */
vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
break;
default: /* Invalid mc_filter_type */
wx_err(wx, "MC filter type param set incorrectly\n");
break;
}
/* vector can only be 12-bits or boundary will be exceeded */
vector &= 0xFFF;
return vector;
}
/**
* wx_set_mta - Set bit-vector in multicast table
* @wx: pointer to private structure
* @mc_addr: Multicast address
*
* Sets the bit-vector in the multicast table.
**/
static void wx_set_mta(struct wx *wx, u8 *mc_addr)
{
u32 vector, vector_bit, vector_reg;
wx->addr_ctrl.mta_in_use++;
vector = wx_mta_vector(wx, mc_addr);
wx_dbg(wx, " bit-vector = 0x%03X\n", vector);
/* The MTA is a register array of 128 32-bit registers. It is treated
* like an array of 4096 bits. We want to set bit
* BitArray[vector_value]. So we figure out what register the bit is
* in, read it, OR in the new bit, then write back the new value. The
* register is determined by the upper 7 bits of the vector value and
* the bit within that register are determined by the lower 5 bits of
* the value.
*/
vector_reg = (vector >> 5) & 0x7F;
vector_bit = vector & 0x1F;
wx->mac.mta_shadow[vector_reg] |= (1 << vector_bit);
}
/**
* wx_update_mc_addr_list - Updates MAC list of multicast addresses
* @wx: pointer to private structure
* @netdev: pointer to net device structure
*
* The given list replaces any existing list. Clears the MC addrs from receive
* address registers and the multicast table. Uses unused receive address
* registers for the first multicast addresses, and hashes the rest into the
* multicast table.
**/
static void wx_update_mc_addr_list(struct wx *wx, struct net_device *netdev)
{
struct netdev_hw_addr *ha;
u32 i, psrctl;
/* Set the new number of MC addresses that we are being requested to
* use.
*/
wx->addr_ctrl.num_mc_addrs = netdev_mc_count(netdev);
wx->addr_ctrl.mta_in_use = 0;
/* Clear mta_shadow */
wx_dbg(wx, " Clearing MTA\n");
memset(&wx->mac.mta_shadow, 0, sizeof(wx->mac.mta_shadow));
/* Update mta_shadow */
netdev_for_each_mc_addr(ha, netdev) {
wx_dbg(wx, " Adding the multicast addresses:\n");
wx_set_mta(wx, ha->addr);
}
/* Enable mta */
for (i = 0; i < wx->mac.mcft_size; i++)
wr32a(wx, WX_PSR_MC_TBL(0), i,
wx->mac.mta_shadow[i]);
if (wx->addr_ctrl.mta_in_use > 0) {
psrctl = rd32(wx, WX_PSR_CTL);
psrctl &= ~(WX_PSR_CTL_MO | WX_PSR_CTL_MFE);
psrctl |= WX_PSR_CTL_MFE |
(wx->mac.mc_filter_type << WX_PSR_CTL_MO_SHIFT);
wr32(wx, WX_PSR_CTL, psrctl);
}
wx_dbg(wx, "Update mc addr list Complete\n");
}
/**
* wx_write_mc_addr_list - write multicast addresses to MTA
* @netdev: network interface device structure
*
* Writes multicast address list to the MTA hash table.
* Returns: 0 on no addresses written
* X on writing X addresses to MTA
**/
static int wx_write_mc_addr_list(struct net_device *netdev)
{
struct wx *wx = netdev_priv(netdev);
if (!netif_running(netdev))
return 0;
wx_update_mc_addr_list(wx, netdev);
return netdev_mc_count(netdev);
}
/** /**
* wx_set_mac - Change the Ethernet Address of the NIC * wx_set_mac - Change the Ethernet Address of the NIC
* @netdev: network interface device structure * @netdev: network interface device structure
...@@ -883,6 +1092,385 @@ void wx_disable_rx(struct wx *wx) ...@@ -883,6 +1092,385 @@ void wx_disable_rx(struct wx *wx)
} }
EXPORT_SYMBOL(wx_disable_rx); EXPORT_SYMBOL(wx_disable_rx);
static void wx_enable_rx(struct wx *wx)
{
u32 psrctl;
/* enable mac receiver */
wr32m(wx, WX_MAC_RX_CFG,
WX_MAC_RX_CFG_RE, WX_MAC_RX_CFG_RE);
wr32m(wx, WX_RDB_PB_CTL,
WX_RDB_PB_CTL_RXEN, WX_RDB_PB_CTL_RXEN);
if (wx->mac.set_lben) {
psrctl = rd32(wx, WX_PSR_CTL);
psrctl |= WX_PSR_CTL_SW_EN;
wr32(wx, WX_PSR_CTL, psrctl);
wx->mac.set_lben = false;
}
}
/**
* wx_set_rxpba - Initialize Rx packet buffer
* @wx: pointer to private structure
**/
static void wx_set_rxpba(struct wx *wx)
{
u32 rxpktsize, txpktsize, txpbthresh;
rxpktsize = wx->mac.rx_pb_size << WX_RDB_PB_SZ_SHIFT;
wr32(wx, WX_RDB_PB_SZ(0), rxpktsize);
/* Only support an equally distributed Tx packet buffer strategy. */
txpktsize = wx->mac.tx_pb_size;
txpbthresh = (txpktsize / 1024) - WX_TXPKT_SIZE_MAX;
wr32(wx, WX_TDB_PB_SZ(0), txpktsize);
wr32(wx, WX_TDM_PB_THRE(0), txpbthresh);
}
static void wx_configure_port(struct wx *wx)
{
u32 value, i;
value = WX_CFG_PORT_CTL_D_VLAN | WX_CFG_PORT_CTL_QINQ;
wr32m(wx, WX_CFG_PORT_CTL,
WX_CFG_PORT_CTL_D_VLAN |
WX_CFG_PORT_CTL_QINQ,
value);
wr32(wx, WX_CFG_TAG_TPID(0),
ETH_P_8021Q | ETH_P_8021AD << 16);
wx->tpid[0] = ETH_P_8021Q;
wx->tpid[1] = ETH_P_8021AD;
for (i = 1; i < 4; i++)
wr32(wx, WX_CFG_TAG_TPID(i),
ETH_P_8021Q | ETH_P_8021Q << 16);
for (i = 2; i < 8; i++)
wx->tpid[i] = ETH_P_8021Q;
}
/**
* wx_disable_sec_rx_path - Stops the receive data path
* @wx: pointer to private structure
*
* Stops the receive data path and waits for the HW to internally empty
* the Rx security block
**/
static int wx_disable_sec_rx_path(struct wx *wx)
{
u32 secrx;
wr32m(wx, WX_RSC_CTL,
WX_RSC_CTL_RX_DIS, WX_RSC_CTL_RX_DIS);
return read_poll_timeout(rd32, secrx, secrx & WX_RSC_ST_RSEC_RDY,
1000, 40000, false, wx, WX_RSC_ST);
}
/**
* wx_enable_sec_rx_path - Enables the receive data path
* @wx: pointer to private structure
*
* Enables the receive data path.
**/
static void wx_enable_sec_rx_path(struct wx *wx)
{
wr32m(wx, WX_RSC_CTL, WX_RSC_CTL_RX_DIS, 0);
WX_WRITE_FLUSH(wx);
}
void wx_set_rx_mode(struct net_device *netdev)
{
struct wx *wx = netdev_priv(netdev);
u32 fctrl, vmolr, vlnctrl;
int count;
/* Check for Promiscuous and All Multicast modes */
fctrl = rd32(wx, WX_PSR_CTL);
fctrl &= ~(WX_PSR_CTL_UPE | WX_PSR_CTL_MPE);
vmolr = rd32(wx, WX_PSR_VM_L2CTL(0));
vmolr &= ~(WX_PSR_VM_L2CTL_UPE |
WX_PSR_VM_L2CTL_MPE |
WX_PSR_VM_L2CTL_ROPE |
WX_PSR_VM_L2CTL_ROMPE);
vlnctrl = rd32(wx, WX_PSR_VLAN_CTL);
vlnctrl &= ~(WX_PSR_VLAN_CTL_VFE | WX_PSR_VLAN_CTL_CFIEN);
/* set all bits that we expect to always be set */
fctrl |= WX_PSR_CTL_BAM | WX_PSR_CTL_MFE;
vmolr |= WX_PSR_VM_L2CTL_BAM |
WX_PSR_VM_L2CTL_AUPE |
WX_PSR_VM_L2CTL_VACC;
vlnctrl |= WX_PSR_VLAN_CTL_VFE;
wx->addr_ctrl.user_set_promisc = false;
if (netdev->flags & IFF_PROMISC) {
wx->addr_ctrl.user_set_promisc = true;
fctrl |= WX_PSR_CTL_UPE | WX_PSR_CTL_MPE;
/* pf don't want packets routing to vf, so clear UPE */
vmolr |= WX_PSR_VM_L2CTL_MPE;
vlnctrl &= ~WX_PSR_VLAN_CTL_VFE;
}
if (netdev->flags & IFF_ALLMULTI) {
fctrl |= WX_PSR_CTL_MPE;
vmolr |= WX_PSR_VM_L2CTL_MPE;
}
if (netdev->features & NETIF_F_RXALL) {
vmolr |= (WX_PSR_VM_L2CTL_UPE | WX_PSR_VM_L2CTL_MPE);
vlnctrl &= ~WX_PSR_VLAN_CTL_VFE;
/* receive bad packets */
wr32m(wx, WX_RSC_CTL,
WX_RSC_CTL_SAVE_MAC_ERR,
WX_RSC_CTL_SAVE_MAC_ERR);
} else {
vmolr |= WX_PSR_VM_L2CTL_ROPE | WX_PSR_VM_L2CTL_ROMPE;
}
/* Write addresses to available RAR registers, if there is not
* sufficient space to store all the addresses then enable
* unicast promiscuous mode
*/
count = wx_write_uc_addr_list(netdev, 0);
if (count < 0) {
vmolr &= ~WX_PSR_VM_L2CTL_ROPE;
vmolr |= WX_PSR_VM_L2CTL_UPE;
}
/* Write addresses to the MTA, if the attempt fails
* then we should just turn on promiscuous mode so
* that we can at least receive multicast traffic
*/
count = wx_write_mc_addr_list(netdev);
if (count < 0) {
vmolr &= ~WX_PSR_VM_L2CTL_ROMPE;
vmolr |= WX_PSR_VM_L2CTL_MPE;
}
wr32(wx, WX_PSR_VLAN_CTL, vlnctrl);
wr32(wx, WX_PSR_CTL, fctrl);
wr32(wx, WX_PSR_VM_L2CTL(0), vmolr);
}
EXPORT_SYMBOL(wx_set_rx_mode);
static void wx_set_rx_buffer_len(struct wx *wx)
{
struct net_device *netdev = wx->netdev;
u32 mhadd, max_frame;
max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
/* adjust max frame to be at least the size of a standard frame */
if (max_frame < (ETH_FRAME_LEN + ETH_FCS_LEN))
max_frame = (ETH_FRAME_LEN + ETH_FCS_LEN);
mhadd = rd32(wx, WX_PSR_MAX_SZ);
if (max_frame != mhadd)
wr32(wx, WX_PSR_MAX_SZ, max_frame);
}
/* Disable the specified rx queue */
void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring)
{
u8 reg_idx = ring->reg_idx;
u32 rxdctl;
int ret;
/* write value back with RRCFG.EN bit cleared */
wr32m(wx, WX_PX_RR_CFG(reg_idx),
WX_PX_RR_CFG_RR_EN, 0);
/* the hardware may take up to 100us to really disable the rx queue */
ret = read_poll_timeout(rd32, rxdctl, !(rxdctl & WX_PX_RR_CFG_RR_EN),
10, 100, true, wx, WX_PX_RR_CFG(reg_idx));
if (ret == -ETIMEDOUT) {
/* Just for information */
wx_err(wx,
"RRCFG.EN on Rx queue %d not cleared within the polling period\n",
reg_idx);
}
}
EXPORT_SYMBOL(wx_disable_rx_queue);
static void wx_enable_rx_queue(struct wx *wx, struct wx_ring *ring)
{
u8 reg_idx = ring->reg_idx;
u32 rxdctl;
int ret;
ret = read_poll_timeout(rd32, rxdctl, rxdctl & WX_PX_RR_CFG_RR_EN,
1000, 10000, true, wx, WX_PX_RR_CFG(reg_idx));
if (ret == -ETIMEDOUT) {
/* Just for information */
wx_err(wx,
"RRCFG.EN on Rx queue %d not set within the polling period\n",
reg_idx);
}
}
static void wx_configure_srrctl(struct wx *wx,
struct wx_ring *rx_ring)
{
u16 reg_idx = rx_ring->reg_idx;
u32 srrctl;
srrctl = rd32(wx, WX_PX_RR_CFG(reg_idx));
srrctl &= ~(WX_PX_RR_CFG_RR_HDR_SZ |
WX_PX_RR_CFG_RR_BUF_SZ |
WX_PX_RR_CFG_SPLIT_MODE);
/* configure header buffer length, needed for RSC */
srrctl |= WX_RXBUFFER_256 << WX_PX_RR_CFG_BHDRSIZE_SHIFT;
/* configure the packet buffer length */
srrctl |= WX_RX_BUFSZ >> WX_PX_RR_CFG_BSIZEPKT_SHIFT;
wr32(wx, WX_PX_RR_CFG(reg_idx), srrctl);
}
static void wx_configure_tx_ring(struct wx *wx,
struct wx_ring *ring)
{
u32 txdctl = WX_PX_TR_CFG_ENABLE;
u8 reg_idx = ring->reg_idx;
int ret;
/* disable queue to avoid issues while updating state */
wr32(wx, WX_PX_TR_CFG(reg_idx), WX_PX_TR_CFG_SWFLSH);
WX_WRITE_FLUSH(wx);
/* reset head and tail pointers */
wr32(wx, WX_PX_TR_RP(reg_idx), 0);
wr32(wx, WX_PX_TR_WP(reg_idx), 0);
ring->tail = wx->hw_addr + WX_PX_TR_WP(reg_idx);
if (ring->count < WX_MAX_TXD)
txdctl |= ring->count / 128 << WX_PX_TR_CFG_TR_SIZE_SHIFT;
txdctl |= 0x20 << WX_PX_TR_CFG_WTHRESH_SHIFT;
/* enable queue */
wr32(wx, WX_PX_TR_CFG(reg_idx), txdctl);
/* poll to verify queue is enabled */
ret = read_poll_timeout(rd32, txdctl, txdctl & WX_PX_TR_CFG_ENABLE,
1000, 10000, true, wx, WX_PX_TR_CFG(reg_idx));
if (ret == -ETIMEDOUT)
wx_err(wx, "Could not enable Tx Queue %d\n", reg_idx);
}
static void wx_configure_rx_ring(struct wx *wx,
struct wx_ring *ring)
{
u16 reg_idx = ring->reg_idx;
u32 rxdctl;
/* disable queue to avoid issues while updating state */
rxdctl = rd32(wx, WX_PX_RR_CFG(reg_idx));
wx_disable_rx_queue(wx, ring);
if (ring->count == WX_MAX_RXD)
rxdctl |= 0 << WX_PX_RR_CFG_RR_SIZE_SHIFT;
else
rxdctl |= (ring->count / 128) << WX_PX_RR_CFG_RR_SIZE_SHIFT;
rxdctl |= 0x1 << WX_PX_RR_CFG_RR_THER_SHIFT;
wr32(wx, WX_PX_RR_CFG(reg_idx), rxdctl);
/* reset head and tail pointers */
wr32(wx, WX_PX_RR_RP(reg_idx), 0);
wr32(wx, WX_PX_RR_WP(reg_idx), 0);
ring->tail = wx->hw_addr + WX_PX_RR_WP(reg_idx);
wx_configure_srrctl(wx, ring);
/* enable receive descriptor ring */
wr32m(wx, WX_PX_RR_CFG(reg_idx),
WX_PX_RR_CFG_RR_EN, WX_PX_RR_CFG_RR_EN);
wx_enable_rx_queue(wx, ring);
}
/**
* wx_configure_tx - Configure Transmit Unit after Reset
* @wx: pointer to private structure
*
* Configure the Tx unit of the MAC after a reset.
**/
static void wx_configure_tx(struct wx *wx)
{
u32 i;
/* TDM_CTL.TE must be before Tx queues are enabled */
wr32m(wx, WX_TDM_CTL,
WX_TDM_CTL_TE, WX_TDM_CTL_TE);
/* Setup the HW Tx Head and Tail descriptor pointers */
for (i = 0; i < wx->num_tx_queues; i++)
wx_configure_tx_ring(wx, wx->tx_ring[i]);
wr32m(wx, WX_TSC_BUF_AE, WX_TSC_BUF_AE_THR, 0x10);
if (wx->mac.type == wx_mac_em)
wr32m(wx, WX_TSC_CTL, WX_TSC_CTL_TX_DIS | WX_TSC_CTL_TSEC_DIS, 0x1);
/* enable mac transmitter */
wr32m(wx, WX_MAC_TX_CFG,
WX_MAC_TX_CFG_TE, WX_MAC_TX_CFG_TE);
}
/**
* wx_configure_rx - Configure Receive Unit after Reset
* @wx: pointer to private structure
*
* Configure the Rx unit of the MAC after a reset.
**/
static void wx_configure_rx(struct wx *wx)
{
u32 psrtype, i;
int ret;
wx_disable_rx(wx);
psrtype = WX_RDB_PL_CFG_L4HDR |
WX_RDB_PL_CFG_L3HDR |
WX_RDB_PL_CFG_L2HDR |
WX_RDB_PL_CFG_TUN_TUNHDR |
WX_RDB_PL_CFG_TUN_TUNHDR;
wr32(wx, WX_RDB_PL_CFG(0), psrtype);
/* enable hw crc stripping */
wr32m(wx, WX_RSC_CTL, WX_RSC_CTL_CRC_STRIP, WX_RSC_CTL_CRC_STRIP);
if (wx->mac.type == wx_mac_sp) {
u32 psrctl;
/* RSC Setup */
psrctl = rd32(wx, WX_PSR_CTL);
psrctl |= WX_PSR_CTL_RSC_ACK; /* Disable RSC for ACK packets */
psrctl |= WX_PSR_CTL_RSC_DIS;
wr32(wx, WX_PSR_CTL, psrctl);
}
/* set_rx_buffer_len must be called before ring initialization */
wx_set_rx_buffer_len(wx);
/* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring
*/
for (i = 0; i < wx->num_rx_queues; i++)
wx_configure_rx_ring(wx, wx->rx_ring[i]);
/* Enable all receives, disable security engine prior to block traffic */
ret = wx_disable_sec_rx_path(wx);
if (ret < 0)
wx_err(wx, "The register status is abnormal, please check device.");
wx_enable_rx(wx);
wx_enable_sec_rx_path(wx);
}
static void wx_configure_isb(struct wx *wx) static void wx_configure_isb(struct wx *wx)
{ {
/* set ISB Address */ /* set ISB Address */
...@@ -893,6 +1481,15 @@ static void wx_configure_isb(struct wx *wx) ...@@ -893,6 +1481,15 @@ static void wx_configure_isb(struct wx *wx)
void wx_configure(struct wx *wx) void wx_configure(struct wx *wx)
{ {
wx_set_rxpba(wx);
wx_configure_port(wx);
wx_set_rx_mode(wx->netdev);
wx_enable_sec_rx_path(wx);
wx_configure_tx(wx);
wx_configure_rx(wx);
wx_configure_isb(wx); wx_configure_isb(wx);
} }
EXPORT_SYMBOL(wx_configure); EXPORT_SYMBOL(wx_configure);
......
...@@ -22,6 +22,8 @@ void wx_mac_set_default_filter(struct wx *wx, u8 *addr); ...@@ -22,6 +22,8 @@ void wx_mac_set_default_filter(struct wx *wx, u8 *addr);
void wx_flush_sw_mac_table(struct wx *wx); void wx_flush_sw_mac_table(struct wx *wx);
int wx_set_mac(struct net_device *netdev, void *p); int wx_set_mac(struct net_device *netdev, void *p);
void wx_disable_rx(struct wx *wx); void wx_disable_rx(struct wx *wx);
void wx_set_rx_mode(struct net_device *netdev);
void wx_disable_rx_queue(struct wx *wx, struct wx_ring *ring);
void wx_configure(struct wx *wx); void wx_configure(struct wx *wx);
int wx_disable_pcie_master(struct wx *wx); int wx_disable_pcie_master(struct wx *wx);
int wx_stop_adapter(struct wx *wx); int wx_stop_adapter(struct wx *wx);
......
...@@ -66,6 +66,9 @@ ...@@ -66,6 +66,9 @@
/* port cfg Registers */ /* port cfg Registers */
#define WX_CFG_PORT_CTL 0x14400 #define WX_CFG_PORT_CTL 0x14400
#define WX_CFG_PORT_CTL_DRV_LOAD BIT(3) #define WX_CFG_PORT_CTL_DRV_LOAD BIT(3)
#define WX_CFG_PORT_CTL_QINQ BIT(2)
#define WX_CFG_PORT_CTL_D_VLAN BIT(0) /* double vlan*/
#define WX_CFG_TAG_TPID(_i) (0x14430 + ((_i) * 4))
/* GPIO Registers */ /* GPIO Registers */
#define WX_GPIO_DR 0x14800 #define WX_GPIO_DR 0x14800
...@@ -88,15 +91,25 @@ ...@@ -88,15 +91,25 @@
#define WX_TDM_CTL 0x18000 #define WX_TDM_CTL 0x18000
/* TDM CTL BIT */ /* TDM CTL BIT */
#define WX_TDM_CTL_TE BIT(0) /* Transmit Enable */ #define WX_TDM_CTL_TE BIT(0) /* Transmit Enable */
#define WX_TDM_PB_THRE(_i) (0x18020 + ((_i) * 4))
/***************************** RDB registers *********************************/ /***************************** RDB registers *********************************/
/* receive packet buffer */ /* receive packet buffer */
#define WX_RDB_PB_CTL 0x19000 #define WX_RDB_PB_CTL 0x19000
#define WX_RDB_PB_CTL_RXEN BIT(31) /* Enable Receiver */ #define WX_RDB_PB_CTL_RXEN BIT(31) /* Enable Receiver */
#define WX_RDB_PB_CTL_DISABLED BIT(0) #define WX_RDB_PB_CTL_DISABLED BIT(0)
#define WX_RDB_PB_SZ(_i) (0x19020 + ((_i) * 4))
#define WX_RDB_PB_SZ_SHIFT 10
/* statistic */ /* statistic */
#define WX_RDB_PFCMACDAL 0x19210 #define WX_RDB_PFCMACDAL 0x19210
#define WX_RDB_PFCMACDAH 0x19214 #define WX_RDB_PFCMACDAH 0x19214
/* ring assignment */
#define WX_RDB_PL_CFG(_i) (0x19300 + ((_i) * 4))
#define WX_RDB_PL_CFG_L4HDR BIT(1)
#define WX_RDB_PL_CFG_L3HDR BIT(2)
#define WX_RDB_PL_CFG_L2HDR BIT(3)
#define WX_RDB_PL_CFG_TUN_TUNHDR BIT(4)
#define WX_RDB_PL_CFG_TUN_OUTL2HDR BIT(5)
/******************************* PSR Registers *******************************/ /******************************* PSR Registers *******************************/
/* psr control */ /* psr control */
...@@ -114,10 +127,24 @@ ...@@ -114,10 +127,24 @@
#define WX_PSR_CTL_MO_SHIFT 5 #define WX_PSR_CTL_MO_SHIFT 5
#define WX_PSR_CTL_MO (0x3 << WX_PSR_CTL_MO_SHIFT) #define WX_PSR_CTL_MO (0x3 << WX_PSR_CTL_MO_SHIFT)
#define WX_PSR_CTL_TPE BIT(4) #define WX_PSR_CTL_TPE BIT(4)
#define WX_PSR_MAX_SZ 0x15020
#define WX_PSR_VLAN_CTL 0x15088
#define WX_PSR_VLAN_CTL_CFIEN BIT(29) /* bit 29 */
#define WX_PSR_VLAN_CTL_VFE BIT(30) /* bit 30 */
/* mcasst/ucast overflow tbl */ /* mcasst/ucast overflow tbl */
#define WX_PSR_MC_TBL(_i) (0x15200 + ((_i) * 4)) #define WX_PSR_MC_TBL(_i) (0x15200 + ((_i) * 4))
#define WX_PSR_UC_TBL(_i) (0x15400 + ((_i) * 4)) #define WX_PSR_UC_TBL(_i) (0x15400 + ((_i) * 4))
/* VM L2 contorl */
#define WX_PSR_VM_L2CTL(_i) (0x15600 + ((_i) * 4))
#define WX_PSR_VM_L2CTL_UPE BIT(4) /* unicast promiscuous */
#define WX_PSR_VM_L2CTL_VACC BIT(6) /* accept nomatched vlan */
#define WX_PSR_VM_L2CTL_AUPE BIT(8) /* accept untagged packets */
#define WX_PSR_VM_L2CTL_ROMPE BIT(9) /* accept packets in MTA tbl */
#define WX_PSR_VM_L2CTL_ROPE BIT(10) /* accept packets in UC tbl */
#define WX_PSR_VM_L2CTL_BAM BIT(11) /* accept broadcast packets */
#define WX_PSR_VM_L2CTL_MPE BIT(12) /* multicast promiscuous */
/* Management */ /* Management */
#define WX_PSR_MNG_FLEX_SEL 0x1582C #define WX_PSR_MNG_FLEX_SEL 0x1582C
#define WX_PSR_MNG_FLEX_DW_L(_i) (0x15A00 + ((_i) * 16)) #define WX_PSR_MNG_FLEX_DW_L(_i) (0x15A00 + ((_i) * 16))
...@@ -139,6 +166,27 @@ ...@@ -139,6 +166,27 @@
#define WX_PSR_MAC_SWC_IDX 0x16210 #define WX_PSR_MAC_SWC_IDX 0x16210
#define WX_CLEAR_VMDQ_ALL 0xFFFFFFFFU #define WX_CLEAR_VMDQ_ALL 0xFFFFFFFFU
/********************************* RSEC **************************************/
/* general rsec */
#define WX_RSC_CTL 0x17000
#define WX_RSC_CTL_SAVE_MAC_ERR BIT(6)
#define WX_RSC_CTL_CRC_STRIP BIT(2)
#define WX_RSC_CTL_RX_DIS BIT(1)
#define WX_RSC_ST 0x17004
#define WX_RSC_ST_RSEC_RDY BIT(0)
/****************************** TDB ******************************************/
#define WX_TDB_PB_SZ(_i) (0x1CC00 + ((_i) * 4))
#define WX_TXPKT_SIZE_MAX 0xA /* Max Tx Packet size */
/****************************** TSEC *****************************************/
/* Security Control Registers */
#define WX_TSC_CTL 0x1D000
#define WX_TSC_CTL_TX_DIS BIT(1)
#define WX_TSC_CTL_TSEC_DIS BIT(0)
#define WX_TSC_BUF_AE 0x1D00C
#define WX_TSC_BUF_AE_THR GENMASK(9, 0)
/************************************** MNG ********************************/ /************************************** MNG ********************************/
#define WX_MNG_SWFW_SYNC 0x1E008 #define WX_MNG_SWFW_SYNC 0x1E008
#define WX_MNG_SWFW_SYNC_SW_MB BIT(2) #define WX_MNG_SWFW_SYNC_SW_MB BIT(2)
...@@ -192,6 +240,10 @@ ...@@ -192,6 +240,10 @@
#define WX_EM_MAX_EITR 0x00007FFCU #define WX_EM_MAX_EITR 0x00007FFCU
/* transmit DMA Registers */ /* transmit DMA Registers */
#define WX_PX_TR_BAL(_i) (0x03000 + ((_i) * 0x40))
#define WX_PX_TR_BAH(_i) (0x03004 + ((_i) * 0x40))
#define WX_PX_TR_WP(_i) (0x03008 + ((_i) * 0x40))
#define WX_PX_TR_RP(_i) (0x0300C + ((_i) * 0x40))
#define WX_PX_TR_CFG(_i) (0x03010 + ((_i) * 0x40)) #define WX_PX_TR_CFG(_i) (0x03010 + ((_i) * 0x40))
/* Transmit Config masks */ /* Transmit Config masks */
#define WX_PX_TR_CFG_ENABLE BIT(0) /* Ena specific Tx Queue */ #define WX_PX_TR_CFG_ENABLE BIT(0) /* Ena specific Tx Queue */
...@@ -201,8 +253,22 @@ ...@@ -201,8 +253,22 @@
#define WX_PX_TR_CFG_THRE_SHIFT 8 #define WX_PX_TR_CFG_THRE_SHIFT 8
/* Receive DMA Registers */ /* Receive DMA Registers */
#define WX_PX_RR_BAL(_i) (0x01000 + ((_i) * 0x40))
#define WX_PX_RR_BAH(_i) (0x01004 + ((_i) * 0x40))
#define WX_PX_RR_WP(_i) (0x01008 + ((_i) * 0x40))
#define WX_PX_RR_RP(_i) (0x0100C + ((_i) * 0x40))
#define WX_PX_RR_CFG(_i) (0x01010 + ((_i) * 0x40)) #define WX_PX_RR_CFG(_i) (0x01010 + ((_i) * 0x40))
/* PX_RR_CFG bit definitions */ /* PX_RR_CFG bit definitions */
#define WX_PX_RR_CFG_SPLIT_MODE BIT(26)
#define WX_PX_RR_CFG_RR_THER_SHIFT 16
#define WX_PX_RR_CFG_RR_HDR_SZ GENMASK(15, 12)
#define WX_PX_RR_CFG_RR_BUF_SZ GENMASK(11, 8)
#define WX_PX_RR_CFG_BHDRSIZE_SHIFT 6 /* 64byte resolution (>> 6)
* + at bit 8 offset (<< 12)
* = (<< 6)
*/
#define WX_PX_RR_CFG_BSIZEPKT_SHIFT 2 /* so many KBs */
#define WX_PX_RR_CFG_RR_SIZE_SHIFT 1
#define WX_PX_RR_CFG_RR_EN BIT(0) #define WX_PX_RR_CFG_RR_EN BIT(0)
/* Number of 80 microseconds we wait for PCI Express master disable */ /* Number of 80 microseconds we wait for PCI Express master disable */
...@@ -230,6 +296,20 @@ ...@@ -230,6 +296,20 @@
#define WX_MAC_STATE_MODIFIED 0x2 #define WX_MAC_STATE_MODIFIED 0x2
#define WX_MAC_STATE_IN_USE 0x4 #define WX_MAC_STATE_IN_USE 0x4
#define WX_MAX_RXD 8192
#define WX_MAX_TXD 8192
/* Supported Rx Buffer Sizes */
#define WX_RXBUFFER_256 256 /* Used for skb receive header */
#define WX_RXBUFFER_2K 2048
#define WX_MAX_RXBUFFER 16384 /* largest size for single descriptor */
#if MAX_SKB_FRAGS < 8
#define WX_RX_BUFSZ ALIGN(WX_MAX_RXBUFFER / MAX_SKB_FRAGS, 1024)
#else
#define WX_RX_BUFSZ WX_RXBUFFER_2K
#endif
#define WX_CFG_PORT_ST 0x14404 #define WX_CFG_PORT_ST 0x14404
/* Host Interface Command Structures */ /* Host Interface Command Structures */
...@@ -307,9 +387,12 @@ struct wx_mac_info { ...@@ -307,9 +387,12 @@ struct wx_mac_info {
bool set_lben; bool set_lben;
u8 addr[ETH_ALEN]; u8 addr[ETH_ALEN];
u8 perm_addr[ETH_ALEN]; u8 perm_addr[ETH_ALEN];
u32 mta_shadow[128];
s32 mc_filter_type; s32 mc_filter_type;
u32 mcft_size; u32 mcft_size;
u32 num_rar_entries; u32 num_rar_entries;
u32 rx_pb_size;
u32 tx_pb_size;
u32 max_tx_queues; u32 max_tx_queues;
u32 max_rx_queues; u32 max_rx_queues;
...@@ -364,6 +447,7 @@ struct wx_ring { ...@@ -364,6 +447,7 @@ struct wx_ring {
struct wx_q_vector *q_vector; /* backpointer to host q_vector */ struct wx_q_vector *q_vector; /* backpointer to host q_vector */
struct net_device *netdev; /* netdev ring belongs to */ struct net_device *netdev; /* netdev ring belongs to */
struct device *dev; /* device for DMA mapping */ struct device *dev; /* device for DMA mapping */
u8 __iomem *tail;
u16 count; /* amount of descriptors */ u16 count; /* amount of descriptors */
...@@ -420,6 +504,7 @@ struct wx { ...@@ -420,6 +504,7 @@ struct wx {
u16 oem_svid; u16 oem_svid;
u16 msg_enable; u16 msg_enable;
bool adapter_stopped; bool adapter_stopped;
u16 tpid[8];
char eeprom_id[32]; char eeprom_id[32];
enum wx_reset_type reset_type; enum wx_reset_type reset_type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment