diff options
author | Christian Ehrhardt <christian.ehrhardt@canonical.com> | 2017-05-16 14:51:32 +0200 |
---|---|---|
committer | Christian Ehrhardt <christian.ehrhardt@canonical.com> | 2017-05-16 14:51:32 +0200 |
commit | fca143f059a0bddd7d47b8dc2df646a891b0eb0f (patch) | |
tree | 4bfeadc905c977e45e54a90c42330553b8942e4e /drivers/net/fm10k/base | |
parent | ce3d555e43e3795b5d9507fcfc76b7a0a92fd0d6 (diff) |
Imported Upstream version 17.05
Diffstat (limited to 'drivers/net/fm10k/base')
-rw-r--r-- | drivers/net/fm10k/base/fm10k_common.c | 11 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_mbx.c | 10 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_mbx.h | 2 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_osdep.h | 34 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_pf.c | 140 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_pf.h | 2 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_tlv.c | 16 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_type.h | 49 | ||||
-rw-r--r-- | drivers/net/fm10k/base/fm10k_vf.c | 24 |
9 files changed, 176 insertions, 112 deletions
diff --git a/drivers/net/fm10k/base/fm10k_common.c b/drivers/net/fm10k/base/fm10k_common.c index a90d2f0b..29f35d7d 100644 --- a/drivers/net/fm10k/base/fm10k_common.c +++ b/drivers/net/fm10k/base/fm10k_common.c @@ -230,6 +230,9 @@ s32 fm10k_disable_queues_generic(struct fm10k_hw *hw, u16 q_cnt) /* clear tx_ready to prevent any false hits for reset */ hw->mac.tx_ready = false; + if (FM10K_REMOVED(hw->hw_addr)) + return FM10K_SUCCESS; + /* clear the enable bit for all rings */ for (i = 0; i < q_cnt; i++) { reg = FM10K_READ_REG(hw, FM10K_TXDCTL(i)); @@ -542,7 +545,7 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready) goto out; /* if we somehow dropped the Tx enable we should reset */ - if (hw->mac.tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) { + if (mac->tx_ready && !(txdctl & FM10K_TXDCTL_ENABLE)) { ret_val = FM10K_ERR_RESET_REQUESTED; goto out; } @@ -558,8 +561,12 @@ s32 fm10k_get_host_state_generic(struct fm10k_hw *hw, bool *host_ready) goto out; /* interface cannot receive traffic without logical ports */ - if (mac->dglort_map == FM10K_DGLORTMAP_NONE) + if (mac->dglort_map == FM10K_DGLORTMAP_NONE) { + if (mac->ops.request_lport_map) + ret_val = mac->ops.request_lport_map(hw); + goto out; + } /* if we passed all the tests above then the switch is ready and we no * longer need to check for link diff --git a/drivers/net/fm10k/base/fm10k_mbx.c b/drivers/net/fm10k/base/fm10k_mbx.c index 2e704340..16ab98d3 100644 --- a/drivers/net/fm10k/base/fm10k_mbx.c +++ b/drivers/net/fm10k/base/fm10k_mbx.c @@ -2066,9 +2066,10 @@ STATIC void fm10k_sm_mbx_create_reply(struct fm10k_hw *hw, * function can also be used to respond to an error as the connection * resetting would also be a means of dealing with errors. **/ -STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, - struct fm10k_mbx_info *mbx) +STATIC s32 fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, + struct fm10k_mbx_info *mbx) { + s32 err = FM10K_SUCCESS; const enum fm10k_mbx_state state = mbx->state; switch (state) { @@ -2081,6 +2082,7 @@ STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, case FM10K_STATE_OPEN: /* flush any incomplete work */ fm10k_sm_mbx_connect_reset(mbx); + err = FM10K_ERR_RESET_REQUESTED; break; case FM10K_STATE_CONNECT: /* Update remote value to match local value */ @@ -2090,6 +2092,8 @@ STATIC void fm10k_sm_mbx_process_reset(struct fm10k_hw *hw, } fm10k_sm_mbx_create_reply(hw, mbx, mbx->tail); + + return err; } /** @@ -2172,7 +2176,7 @@ STATIC s32 fm10k_sm_mbx_process(struct fm10k_hw *hw, switch (FM10K_MSG_HDR_FIELD_GET(mbx->mbx_hdr, SM_VER)) { case 0: - fm10k_sm_mbx_process_reset(hw, mbx); + err = fm10k_sm_mbx_process_reset(hw, mbx); break; case FM10K_SM_MBX_VERSION: err = fm10k_sm_mbx_process_version_1(hw, mbx); diff --git a/drivers/net/fm10k/base/fm10k_mbx.h b/drivers/net/fm10k/base/fm10k_mbx.h index edc57dff..2fac012c 100644 --- a/drivers/net/fm10k/base/fm10k_mbx.h +++ b/drivers/net/fm10k/base/fm10k_mbx.h @@ -54,6 +54,8 @@ struct fm10k_mbx_info; #define FM10K_MBX_ACK_INTERRUPT 0x00000010 #define FM10K_MBX_INTERRUPT_ENABLE 0x00000020 #define FM10K_MBX_INTERRUPT_DISABLE 0x00000040 +#define FM10K_MBX_GLOBAL_REQ_INTERRUPT 0x00000200 +#define FM10K_MBX_GLOBAL_ACK_INTERRUPT 0x00000400 #define FM10K_MBICR(_n) ((_n) + 0x18840) #define FM10K_GMBX 0x18842 diff --git a/drivers/net/fm10k/base/fm10k_osdep.h b/drivers/net/fm10k/base/fm10k_osdep.h index a21daa2a..199ebd8e 100644 --- a/drivers/net/fm10k/base/fm10k_osdep.h +++ b/drivers/net/fm10k/base/fm10k_osdep.h @@ -39,6 +39,8 @@ POSSIBILITY OF SUCH DAMAGE. #include <rte_atomic.h> #include <rte_byteorder.h> #include <rte_cycles.h> +#include <rte_io.h> + #include "../fm10k_logs.h" /* TODO: this does not look like it should be used... */ @@ -88,17 +90,16 @@ typedef int bool; #endif /* offsets are WORD offsets, not BYTE offsets */ -#define FM10K_WRITE_REG(hw, reg, val) \ - ((((volatile uint32_t *)(hw)->hw_addr)[(reg)]) = ((uint32_t)(val))) -#define FM10K_READ_REG(hw, reg) \ - (((volatile uint32_t *)(hw)->hw_addr)[(reg)]) +#define FM10K_WRITE_REG(hw, reg, val) \ + rte_write32((val), ((hw)->hw_addr + (reg))) + +#define FM10K_READ_REG(hw, reg) rte_read32(((hw)->hw_addr + (reg))) + #define FM10K_WRITE_FLUSH(a) FM10K_READ_REG(a, FM10K_CTRL) -#define FM10K_PCI_REG(reg) (*((volatile uint32_t *)(reg))) +#define FM10K_PCI_REG(reg) rte_read32(reg) -#define FM10K_PCI_REG_WRITE(reg, value) do { \ - FM10K_PCI_REG((reg)) = (value); \ -} while (0) +#define FM10K_PCI_REG_WRITE(reg, value) rte_write32((value), (reg)) /* not implemented */ #define FM10K_READ_PCI_WORD(hw, reg) 0 @@ -162,23 +163,6 @@ typedef int bool; #define FM10K_RXD_PKTTYPE_MASK 0x03F0 #define FM10K_RXD_PKTTYPE_SHIFT 4 -enum fm10k_rdesc_pkt_type { - /* L3 type */ - FM10K_PKTTYPE_OTHER = 0x00, - FM10K_PKTTYPE_IPV4 = 0x01, - FM10K_PKTTYPE_IPV4_EX = 0x02, - FM10K_PKTTYPE_IPV6 = 0x03, - FM10K_PKTTYPE_IPV6_EX = 0x04, - - /* L4 type */ - FM10K_PKTTYPE_TCP = 0x08, - FM10K_PKTTYPE_UDP = 0x10, - FM10K_PKTTYPE_GRE = 0x18, - FM10K_PKTTYPE_VXLAN = 0x20, - FM10K_PKTTYPE_NVGRE = 0x28, - FM10K_PKTTYPE_GENEVE = 0x30 -}; - #define FM10K_RXD_STATUS_IPCS 0x0008 /* Indicates IPv4 csum */ #define FM10K_RXD_STATUS_HBO 0x0400 /* header buffer overrun */ diff --git a/drivers/net/fm10k/base/fm10k_pf.c b/drivers/net/fm10k/base/fm10k_pf.c index 105babf4..db5f4912 100644 --- a/drivers/net/fm10k/base/fm10k_pf.c +++ b/drivers/net/fm10k/base/fm10k_pf.c @@ -66,21 +66,21 @@ STATIC s32 fm10k_reset_hw_pf(struct fm10k_hw *hw) /* shut down all rings */ err = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES); - if (err) + if (err == FM10K_ERR_REQUESTS_PENDING) { + hw->mac.reset_while_pending++; + goto force_reset; + } else if (err) { return err; + } /* Verify that DMA is no longer active */ reg = FM10K_READ_REG(hw, FM10K_DMA_CTRL); if (reg & (FM10K_DMA_CTRL_TX_ACTIVE | FM10K_DMA_CTRL_RX_ACTIVE)) return FM10K_ERR_DMA_PENDING; - /* verify the switch is ready for reset */ - reg = FM10K_READ_REG(hw, FM10K_DMA_CTRL2); - if (!(reg & FM10K_DMA_CTRL2_SWITCH_READY)) - goto out; - +force_reset: /* Inititate data path reset */ - reg |= FM10K_DMA_CTRL_DATAPATH_RESET; + reg = FM10K_DMA_CTRL_DATAPATH_RESET; FM10K_WRITE_REG(hw, FM10K_DMA_CTRL, reg); /* Flush write and allow 100us for reset to complete */ @@ -90,10 +90,9 @@ STATIC s32 fm10k_reset_hw_pf(struct fm10k_hw *hw) /* Verify we made it out of reset */ reg = FM10K_READ_REG(hw, FM10K_IP); if (!(reg & FM10K_IP_NOTINRESET)) - err = FM10K_ERR_RESET_FAILED; + return FM10K_ERR_RESET_FAILED; -out: - return err; + return FM10K_SUCCESS; } /** @@ -255,8 +254,8 @@ STATIC s32 fm10k_update_vlan_pf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set) /* VLAN multi-bit write: * The multi-bit write has several parts to it. - * 3 2 1 0 - * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + * 24 16 8 0 + * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | RSVD0 | Length |C|RSVD0| VLAN ID | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -412,7 +411,7 @@ STATIC s32 fm10k_update_uc_addr_pf(struct fm10k_hw *hw, u16 glort, DEBUGFUNC("fm10k_update_uc_addr_pf"); /* verify MAC address is valid */ - if (!FM10K_IS_VALID_ETHER_ADDR(mac)) + if (!IS_VALID_ETHER_ADDR(mac)) return FM10K_ERR_PARAM; return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, flags); @@ -435,7 +434,7 @@ STATIC s32 fm10k_update_mc_addr_pf(struct fm10k_hw *hw, u16 glort, DEBUGFUNC("fm10k_update_mc_addr_pf"); /* verify multicast address is valid */ - if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac)) + if (!IS_MULTICAST_ETHER_ADDR(mac)) return FM10K_ERR_PARAM; return fm10k_update_xc_addr_pf(hw, glort, mac, vid, add, 0); @@ -536,6 +535,10 @@ STATIC s32 fm10k_update_lport_state_pf(struct fm10k_hw *hw, u16 glort, if (!fm10k_glort_valid_pf(hw, glort)) return FM10K_ERR_PARAM; + /* reset multicast mode if deleting lport */ + if (!enable) + fm10k_update_xcast_mode_pf(hw, glort, FM10K_XCAST_MODE_NONE); + /* construct the lport message from the 2 pieces of data we have */ lport_msg = ((u32)count << 16) | glort; @@ -908,13 +911,13 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw, vf_q_idx = fm10k_vf_queue_index(hw, vf_idx); qmap_idx = qmap_stride * vf_idx; - /* MAP Tx queue back to 0 temporarily, and disable it */ - FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0); - FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0); - - /* determine correct default VLAN ID */ + /* Determine correct default VLAN ID. The FM10K_VLAN_OVERRIDE bit is + * used here to indicate to the VF that it will not have privilege to + * write VLAN_TABLE. All policy is enforced on the PF but this allows + * the VF to correctly report errors to userspace rqeuests. + */ if (vf_info->pf_vid) - vf_vid = vf_info->pf_vid | FM10K_VLAN_CLEAR; + vf_vid = vf_info->pf_vid | FM10K_VLAN_OVERRIDE; else vf_vid = vf_info->sw_vid; @@ -923,9 +926,35 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw, fm10k_tlv_attr_put_mac_vlan(msg, FM10K_MAC_VLAN_MSG_DEFAULT_MAC, vf_info->mac, vf_vid); - /* load onto outgoing mailbox, ignore any errors on enqueue */ - if (vf_info->mbx.ops.enqueue_tx) - vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg); + /* Configure Queue control register with new VLAN ID. The TXQCTL + * register is RO from the VF, so the PF must do this even in the + * case of notifying the VF of a new VID via the mailbox. + */ + txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) & + FM10K_TXQCTL_VID_MASK; + txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) | + FM10K_TXQCTL_VF | vf_idx; + + for (i = 0; i < queues_per_pool; i++) + FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl); + + /* try loading a message onto outgoing mailbox first */ + if (vf_info->mbx.ops.enqueue_tx) { + err = vf_info->mbx.ops.enqueue_tx(hw, &vf_info->mbx, msg); + if (err != FM10K_MBX_ERR_NO_MBX) + return err; + err = FM10K_SUCCESS; + } + + /* If we aren't connected to a mailbox, this is most likely because + * the VF driver is not running. It should thus be safe to re-map + * queues and use the registers to pass the MAC address so that the VF + * driver gets correct information during its initialization. + */ + + /* MAP Tx queue back to 0 temporarily, and disable it */ + FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), 0); + FM10K_WRITE_REG(hw, FM10K_TXDCTL(vf_q_idx), 0); /* verify ring has disabled before modifying base address registers */ txdctl = FM10K_READ_REG(hw, FM10K_TXDCTL(vf_q_idx)); @@ -941,7 +970,7 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw, } /* Update base address registers to contain MAC address */ - if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) { + if (IS_VALID_ETHER_ADDR(vf_info->mac)) { tdbal = (((u32)vf_info->mac[3]) << 24) | (((u32)vf_info->mac[4]) << 16) | (((u32)vf_info->mac[5]) << 8); @@ -964,16 +993,6 @@ STATIC s32 fm10k_iov_assign_default_mac_vlan_pf(struct fm10k_hw *hw, FM10K_TDLEN_ITR_SCALE_SHIFT); err_out: - /* configure Queue control register */ - txqctl = ((u32)vf_vid << FM10K_TXQCTL_VID_SHIFT) & - FM10K_TXQCTL_VID_MASK; - txqctl |= (vf_idx << FM10K_TXQCTL_TC_SHIFT) | - FM10K_TXQCTL_VF | vf_idx; - - /* assign VLAN ID */ - for (i = 0; i < queues_per_pool; i++) - FM10K_WRITE_REG(hw, FM10K_TXQCTL(vf_q_idx + i), txqctl); - /* restore the queue back to VF ownership */ FM10K_WRITE_REG(hw, FM10K_TQMAP(qmap_idx), vf_q_idx); return err; @@ -1081,7 +1100,7 @@ STATIC s32 fm10k_iov_reset_resources_pf(struct fm10k_hw *hw, FM10K_WRITE_REG(hw, FM10K_MRQC(vf_info->vsi), 0); /* Update base address registers to contain MAC address */ - if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac)) { + if (IS_VALID_ETHER_ADDR(vf_info->mac)) { tdbal = (((u32)vf_info->mac[3]) << 24) | (((u32)vf_info->mac[4]) << 16) | (((u32)vf_info->mac[5]) << 8); @@ -1267,18 +1286,32 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results, if (err) return err; - /* verify upper 16 bits are zero */ - if (vid >> 16) - return FM10K_ERR_PARAM; - set = !(vid & FM10K_VLAN_CLEAR); vid &= ~FM10K_VLAN_CLEAR; - err = fm10k_iov_select_vid(vf_info, (u16)vid); - if (err < 0) - return err; + /* if the length field has been set, this is a multi-bit + * update request. For multi-bit requests, simply disallow + * them when the pf_vid has been set. In this case, the PF + * should have already cleared the VLAN_TABLE, and if we + * allowed them, it could allow a rogue VF to receive traffic + * on a VLAN it was not assigned. In the single-bit case, we + * need to modify requests for VLAN 0 to use the default PF or + * SW vid when assigned. + */ - vid = err; + if (vid >> 16) { + /* prevent multi-bit requests when PF has + * administratively set the VLAN for this VF + */ + if (vf_info->pf_vid) + return FM10K_ERR_PARAM; + } else { + err = fm10k_iov_select_vid(vf_info, (u16)vid); + if (err < 0) + return err; + + vid = err; + } /* update VSI info for VF in regards to VLAN table */ err = hw->mac.ops.update_vlan(hw, vid, vf_info->vsi, set); @@ -1293,7 +1326,7 @@ s32 fm10k_iov_msg_mac_vlan_pf(struct fm10k_hw *hw, u32 **results, return err; /* block attempts to set MAC for a locked device */ - if (FM10K_IS_VALID_ETHER_ADDR(vf_info->mac) && + if (IS_VALID_ETHER_ADDR(vf_info->mac) && memcmp(mac, vf_info->mac, ETH_ALEN)) return FM10K_ERR_PARAM; @@ -1670,13 +1703,12 @@ STATIC s32 fm10k_request_lport_map_pf(struct fm10k_hw *hw) * @hw: pointer to hardware structure * @switch_ready: pointer to boolean value that will record switch state * - * This funciton will check the DMA_CTRL2 register and mailbox in order + * This function will check the DMA_CTRL2 register and mailbox in order * to determine if the switch is ready for the PF to begin requesting * addresses and mapping traffic to the local interface. **/ STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready) { - s32 ret_val = FM10K_SUCCESS; u32 dma_ctrl2; DEBUGFUNC("fm10k_get_host_state_pf"); @@ -1684,23 +1716,16 @@ STATIC s32 fm10k_get_host_state_pf(struct fm10k_hw *hw, bool *switch_ready) /* verify the switch is ready for interaction */ dma_ctrl2 = FM10K_READ_REG(hw, FM10K_DMA_CTRL2); if (!(dma_ctrl2 & FM10K_DMA_CTRL2_SWITCH_READY)) - goto out; + return FM10K_SUCCESS; /* retrieve generic host state info */ - ret_val = fm10k_get_host_state_generic(hw, switch_ready); - if (ret_val) - goto out; - - /* interface cannot receive traffic without logical ports */ - if (hw->mac.dglort_map == FM10K_DGLORTMAP_NONE) - ret_val = fm10k_request_lport_map_pf(hw); - -out: - return ret_val; + return fm10k_get_host_state_generic(hw, switch_ready); } /* This structure defines the attibutes to be parsed below */ const struct fm10k_tlv_attr fm10k_lport_map_msg_attr[] = { + FM10K_TLV_ATTR_LE_STRUCT(FM10K_PF_ATTR_ID_ERR, + sizeof(struct fm10k_swapi_error)), FM10K_TLV_ATTR_U32(FM10K_PF_ATTR_ID_LPORT_MAP), FM10K_TLV_ATTR_LAST }; @@ -2082,6 +2107,7 @@ s32 fm10k_init_ops_pf(struct fm10k_hw *hw) mac->ops.set_dma_mask = &fm10k_set_dma_mask_pf; mac->ops.get_fault = &fm10k_get_fault_pf; mac->ops.get_host_state = &fm10k_get_host_state_pf; + mac->ops.request_lport_map = &fm10k_request_lport_map_pf; mac->ops.adjust_systime = &fm10k_adjust_systime_pf; mac->ops.notify_offset = &fm10k_notify_offset_pf; mac->ops.read_systime = &fm10k_read_systime_pf; diff --git a/drivers/net/fm10k/base/fm10k_pf.h b/drivers/net/fm10k/base/fm10k_pf.h index c84b1bc5..ca125c27 100644 --- a/drivers/net/fm10k/base/fm10k_pf.h +++ b/drivers/net/fm10k/base/fm10k_pf.h @@ -91,6 +91,8 @@ enum fm10k_pf_tlv_attr_id_v1 { #define FM10K_MSG_UPDATE_PVID_PVID_SHIFT 16 #define FM10K_MSG_UPDATE_PVID_PVID_SIZE 16 +#define FM10K_MSG_ERR_PEP_NOT_SCHEDULED 280 + /* The following data structures are overlayed directly onto TLV mailbox * messages, and must not break 4 byte alignment. Ensure the structures line * up correctly as per their TLV definition. diff --git a/drivers/net/fm10k/base/fm10k_tlv.c b/drivers/net/fm10k/base/fm10k_tlv.c index e6150c1d..0328ede2 100644 --- a/drivers/net/fm10k/base/fm10k_tlv.c +++ b/drivers/net/fm10k/base/fm10k_tlv.c @@ -520,7 +520,8 @@ STATIC s32 fm10k_tlv_attr_validate(u32 *attr, * up into an array of pointers stored in results. The function will * return FM10K_ERR_PARAM on any input or message error, * FM10K_NOT_IMPLEMENTED for any attribute that is outside of the array - * and 0 on success. + * and 0 on success. Any attributes not found in tlv_attr will be silently + * ignored. **/ static s32 fm10k_tlv_attr_parse(u32 *attr, u32 **results, const struct fm10k_tlv_attr *tlv_attr) @@ -559,14 +560,15 @@ static s32 fm10k_tlv_attr_parse(u32 *attr, u32 **results, while (offset < len) { attr_id = *attr & FM10K_TLV_ID_MASK; - if (attr_id < FM10K_TLV_RESULTS_MAX) - err = fm10k_tlv_attr_validate(attr, tlv_attr); - else - err = FM10K_NOT_IMPLEMENTED; + if (attr_id >= FM10K_TLV_RESULTS_MAX) + return FM10K_NOT_IMPLEMENTED; - if (err < 0) + err = fm10k_tlv_attr_validate(attr, tlv_attr); + if (err == FM10K_NOT_IMPLEMENTED) + ; /* silently ignore non-implemented attributes */ + else if (err) return err; - if (!err) + else results[attr_id] = attr; /* update offset */ diff --git a/drivers/net/fm10k/base/fm10k_type.h b/drivers/net/fm10k/base/fm10k_type.h index 3fc8f136..1f38a02c 100644 --- a/drivers/net/fm10k/base/fm10k_type.h +++ b/drivers/net/fm10k/base/fm10k_type.h @@ -40,6 +40,7 @@ struct fm10k_hw; #include "fm10k_osdep.h" #include "fm10k_mbx.h" +#define FM10K_INTEL_VENDOR_ID 0x8086 #define FM10K_DEV_ID_PF 0x15A4 #define FM10K_DEV_ID_VF 0x15A5 #ifdef BOULDER_RAPIDS_HW @@ -125,11 +126,15 @@ struct fm10k_hw; /* Interrupt control registers */ #define FM10K_EICR 0x0006 +#define FM10K_EICR_PCA_FAULT 0x00000001 +#define FM10K_EICR_THI_FAULT 0x00000004 +#define FM10K_EICR_FUM_FAULT 0x00000020 #define FM10K_EICR_FAULT_MASK 0x0000003F #define FM10K_EICR_MAILBOX 0x00000040 #define FM10K_EICR_SWITCHREADY 0x00000080 #define FM10K_EICR_SWITCHNOTREADY 0x00000100 #define FM10K_EICR_SWITCHINTERRUPT 0x00000200 +#define FM10K_EICR_SRAMERROR 0x00000400 #define FM10K_EICR_VFLR 0x00000800 #define FM10K_EICR_MAXHOLDTIME 0x00001000 #define FM10K_EIMR 0x0007 @@ -183,6 +188,7 @@ struct fm10k_hw; #define FM10K_DGLORTDEC_INNERRSS_ENABLE 0x08000000 #define FM10K_TUNNEL_CFG 0x0040 #define FM10K_TUNNEL_CFG_NVGRE_SHIFT 16 +#define FM10K_TUNNEL_CFG_GENEVE 0x0041 #define FM10K_SWPRI_MAP(_n) ((_n) + 0x0050) #define FM10K_SWPRI_MAX 16 #define FM10K_RSSRK(_n, _m) (((_n) * 0x10) + (_m) + 0x0800) @@ -211,6 +217,7 @@ struct fm10k_hw; #define FM10K_DMA_CTRL_RX_ENABLE 0x00000010 #define FM10K_DMA_CTRL_RX_ACTIVE 0x00000080 #define FM10K_DMA_CTRL_RX_DESC_SIZE 0x00000100 +#define FM10K_DMA_CTRL_MINMSS_SHIFT 9 #define FM10K_DMA_CTRL_MINMSS_64 0x00008000 #define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN3 0x04800000 #define FM10K_DMA_CTRL_MAX_HOLD_1US_GEN2 0x04000000 @@ -283,6 +290,7 @@ struct fm10k_hw; #define FM10K_RXDCTL_WRITE_BACK_MIN_DELAY 0x00000001 #define FM10K_RXDCTL_DROP_ON_EMPTY 0x00000200 #define FM10K_RXINT(_n) ((0x40 * (_n)) + 0x4008) +#define FM10K_RXINT_TIMER_SHIFT 8 #define FM10K_SRRCTL(_n) ((0x40 * (_n)) + 0x4009) #define FM10K_SRRCTL_BSIZEPKT_SHIFT 8 /* shift _right_ */ #define FM10K_SRRCTL_LOOPBACK_SUPPRESS 0x40000000 @@ -336,6 +344,7 @@ struct fm10k_hw; #define FM10K_TXQCTL_VID_MASK 0x0FFF0000 #define FM10K_TXQCTL_UNLIMITED_BW 0x10000000 #define FM10K_TXINT(_n) ((0x40 * (_n)) + 0x8008) +#define FM10K_TXINT_TIMER_SHIFT 8 /* Tx Statistics */ #define FM10K_QPTC(_n) ((0x40 * (_n)) + 0x8009) @@ -374,6 +383,7 @@ struct fm10k_hw; /* Switch manager interrupt registers */ #define FM10K_IP 0x13000 #define FM10K_IP_NOTINRESET 0x00000100 +#define FM10K_SRAM_IP 0x13003 /* VLAN registers */ #define FM10K_VLAN_TABLE(_n, _m) ((0x80 * (_n)) + (_m) + 0x14000) @@ -384,6 +394,7 @@ struct fm10k_hw; #define FM10K_VLAN_TABLE_VSI_MAX 64 #define FM10K_VLAN_LENGTH_SHIFT 16 #define FM10K_VLAN_CLEAR BIT(15) +#define FM10K_VLAN_OVERRIDE FM10K_VLAN_CLEAR #define FM10K_VLAN_ALL \ ((FM10K_VLAN_TABLE_VID_MAX - 1) << FM10K_VLAN_LENGTH_SHIFT) @@ -422,20 +433,20 @@ struct fm10k_hw; #define ETH_ALEN 6 #endif /* ETH_ALEN */ -#ifndef FM10K_IS_ZERO_ETHER_ADDR +#ifndef IS_ZERO_ETHER_ADDR /* make certain address is not 0 */ -#define FM10K_IS_ZERO_ETHER_ADDR(addr) \ +#define IS_ZERO_ETHER_ADDR(addr) \ (!((addr)[0] | (addr)[1] | (addr)[2] | (addr)[3] | (addr)[4] | (addr)[5])) #endif -#ifndef FM10K_IS_MULTICAST_ETHER_ADDR -#define FM10K_IS_MULTICAST_ETHER_ADDR(addr) ((addr)[0] & 0x1) +#ifndef IS_MULTICAST_ETHER_ADDR +#define IS_MULTICAST_ETHER_ADDR(addr) ((addr)[0] & 0x1) #endif -#ifndef FM10K_IS_VALID_ETHER_ADDR +#ifndef IS_VALID_ETHER_ADDR /* make certain address is not multicast or 0 */ -#define FM10K_IS_VALID_ETHER_ADDR(addr) \ -(!FM10K_IS_MULTICAST_ETHER_ADDR(addr) && !FM10K_IS_ZERO_ETHER_ADDR(addr)) +#define IS_VALID_ETHER_ADDR(addr) \ +(!IS_MULTICAST_ETHER_ADDR(addr) && !IS_ZERO_ETHER_ADDR(addr)) #endif enum fm10k_int_source { @@ -587,6 +598,7 @@ struct fm10k_mac_ops { s32 (*stop_hw)(struct fm10k_hw *); s32 (*get_bus_info)(struct fm10k_hw *); s32 (*get_host_state)(struct fm10k_hw *, bool *); + s32 (*request_lport_map)(struct fm10k_hw *); #ifndef NO_IS_SLOT_APPROPRIATE_CHECK bool (*is_slot_appropriate)(struct fm10k_hw *); #endif @@ -629,6 +641,7 @@ struct fm10k_mac_info { bool tx_ready; u32 dglort_map; u8 itr_scale; + u64 reset_while_pending; }; struct fm10k_swapi_table_info { @@ -676,6 +689,9 @@ struct fm10k_vf_info { u8 vf_flags; /* flags indicating what modes * are supported for the port */ +#ifndef NO_FM10K_VF_TRUSTED_MODE + bool trusted; /* VF trust mode */ +#endif }; #define FM10K_VF_FLAG_ALLMULTI_CAPABLE (u8)(BIT(FM10K_XCAST_MODE_ALLMULTI)) @@ -812,6 +828,24 @@ enum fm10k_rdesc_rss_type { /* Reserved 0x9 - 0xF */ }; +#define FM10K_RXD_PKTTYPE_MASK 0x03F0 +#define FM10K_RXD_PKTTYPE_SHIFT 4 +enum fm10k_rdesc_pkt_type { + /* L3 type */ + FM10K_PKTTYPE_OTHER = 0x00, + FM10K_PKTTYPE_IPV4 = 0x01, + FM10K_PKTTYPE_IPV4_EX = 0x02, + FM10K_PKTTYPE_IPV6 = 0x03, + FM10K_PKTTYPE_IPV6_EX = 0x04, + + /* L4 type */ + FM10K_PKTTYPE_TCP = 0x08, + FM10K_PKTTYPE_UDP = 0x10, + FM10K_PKTTYPE_GRE = 0x18, + FM10K_PKTTYPE_VXLAN = 0x20, + FM10K_PKTTYPE_NVGRE = 0x28, + FM10K_PKTTYPE_GENEVE = 0x30 +}; #define FM10K_RXD_HDR_INFO_XC_MASK 0x0006 enum fm10k_rxdesc_xc { @@ -823,6 +857,7 @@ enum fm10k_rxdesc_xc { #define FM10K_RXD_STATUS_DD 0x0001 /* Descriptor done */ #define FM10K_RXD_STATUS_EOP 0x0002 /* End of packet */ +#define FM10K_RXD_STATUS_IPCS 0x0008 /* Indicates IPv4 csum */ #define FM10K_RXD_STATUS_L4CS 0x0010 /* Indicates an L4 csum */ #define FM10K_RXD_STATUS_L4CS2 0x0040 /* Inner header L4 csum */ #define FM10K_RXD_STATUS_L4E2 0x0800 /* Inner header L4 csum err */ diff --git a/drivers/net/fm10k/base/fm10k_vf.c b/drivers/net/fm10k/base/fm10k_vf.c index efbdbd1e..bd449773 100644 --- a/drivers/net/fm10k/base/fm10k_vf.c +++ b/drivers/net/fm10k/base/fm10k_vf.c @@ -49,11 +49,11 @@ STATIC s32 fm10k_stop_hw_vf(struct fm10k_hw *hw) /* we need to disable the queues before taking further steps */ err = fm10k_stop_hw_generic(hw); - if (err) + if (err && err != FM10K_ERR_REQUESTS_PENDING) return err; /* If permanent address is set then we need to restore it */ - if (FM10K_IS_VALID_ETHER_ADDR(perm_addr)) { + if (IS_VALID_ETHER_ADDR(perm_addr)) { bal = (((u32)perm_addr[3]) << 24) | (((u32)perm_addr[4]) << 16) | (((u32)perm_addr[5]) << 8); @@ -82,7 +82,7 @@ STATIC s32 fm10k_stop_hw_vf(struct fm10k_hw *hw) FM10K_WRITE_REG(hw, FM10K_TDLEN(i), tdlen); } - return FM10K_SUCCESS; + return err; } /** @@ -100,7 +100,9 @@ STATIC s32 fm10k_reset_hw_vf(struct fm10k_hw *hw) /* shut down queues we own and reset DMA configuration */ err = fm10k_stop_hw_vf(hw); - if (err) + if (err == FM10K_ERR_REQUESTS_PENDING) + hw->mac.reset_while_pending++; + else if (err) return err; /* Inititate VF reset */ @@ -113,9 +115,9 @@ STATIC s32 fm10k_reset_hw_vf(struct fm10k_hw *hw) /* Clear reset bit and verify it was cleared */ FM10K_WRITE_REG(hw, FM10K_VFCTRL, 0); if (FM10K_READ_REG(hw, FM10K_VFCTRL) & FM10K_VFCTRL_RST) - err = FM10K_ERR_RESET_FAILED; + return FM10K_ERR_RESET_FAILED; - return err; + return FM10K_SUCCESS; } /** @@ -225,7 +227,7 @@ STATIC s32 fm10k_update_vlan_vf(struct fm10k_hw *hw, u32 vid, u8 vsi, bool set) if (vsi) return FM10K_ERR_PARAM; - /* verify upper 4 bits of vid and length are 0 */ + /* clever trick to verify reserved bits in both vid and length */ if ((vid << 16 | vid) >> 28) return FM10K_ERR_PARAM; @@ -268,7 +270,7 @@ s32 fm10k_msg_mac_vlan_vf(struct fm10k_hw *hw, u32 **results, memcpy(hw->mac.perm_addr, perm_addr, ETH_ALEN); hw->mac.default_vid = vid & (FM10K_VLAN_TABLE_VID_MAX - 1); - hw->mac.vlan_override = !!(vid & FM10K_VLAN_CLEAR); + hw->mac.vlan_override = !!(vid & FM10K_VLAN_OVERRIDE); return FM10K_SUCCESS; } @@ -339,11 +341,11 @@ STATIC s32 fm10k_update_uc_addr_vf(struct fm10k_hw *hw, u16 glort, return FM10K_ERR_PARAM; /* verify MAC address is valid */ - if (!FM10K_IS_VALID_ETHER_ADDR(mac)) + if (!IS_VALID_ETHER_ADDR(mac)) return FM10K_ERR_PARAM; /* verify we are not locked down on the MAC address */ - if (FM10K_IS_VALID_ETHER_ADDR(hw->mac.perm_addr) && + if (IS_VALID_ETHER_ADDR(hw->mac.perm_addr) && memcmp(hw->mac.perm_addr, mac, ETH_ALEN)) return FM10K_ERR_PARAM; @@ -385,7 +387,7 @@ STATIC s32 fm10k_update_mc_addr_vf(struct fm10k_hw *hw, u16 glort, return FM10K_ERR_PARAM; /* verify multicast address is valid */ - if (!FM10K_IS_MULTICAST_ETHER_ADDR(mac)) + if (!IS_MULTICAST_ETHER_ADDR(mac)) return FM10K_ERR_PARAM; /* add bit to notify us if this is a set or clear operation */ |