|
@@ -75,12 +75,22 @@ enum board_idx {
|
|
BCM57301,
|
|
BCM57301,
|
|
BCM57302,
|
|
BCM57302,
|
|
BCM57304,
|
|
BCM57304,
|
|
|
|
+ BCM57311,
|
|
|
|
+ BCM57312,
|
|
BCM57402,
|
|
BCM57402,
|
|
BCM57404,
|
|
BCM57404,
|
|
BCM57406,
|
|
BCM57406,
|
|
|
|
+ BCM57404_NPAR,
|
|
|
|
+ BCM57412,
|
|
|
|
+ BCM57414,
|
|
|
|
+ BCM57416,
|
|
|
|
+ BCM57417,
|
|
|
|
+ BCM57414_NPAR,
|
|
BCM57314,
|
|
BCM57314,
|
|
BCM57304_VF,
|
|
BCM57304_VF,
|
|
BCM57404_VF,
|
|
BCM57404_VF,
|
|
|
|
+ BCM57414_VF,
|
|
|
|
+ BCM57314_VF,
|
|
};
|
|
};
|
|
|
|
|
|
/* indexed by enum above */
|
|
/* indexed by enum above */
|
|
@@ -90,25 +100,45 @@ static const struct {
|
|
{ "Broadcom BCM57301 NetXtreme-C Single-port 10Gb Ethernet" },
|
|
{ "Broadcom BCM57301 NetXtreme-C Single-port 10Gb Ethernet" },
|
|
{ "Broadcom BCM57302 NetXtreme-C Dual-port 10Gb/25Gb Ethernet" },
|
|
{ "Broadcom BCM57302 NetXtreme-C Dual-port 10Gb/25Gb Ethernet" },
|
|
{ "Broadcom BCM57304 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
|
{ "Broadcom BCM57304 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
|
|
|
+ { "Broadcom BCM57311 NetXtreme-C Single-port 10Gb Ethernet" },
|
|
|
|
+ { "Broadcom BCM57312 NetXtreme-C Dual-port 10Gb/25Gb Ethernet" },
|
|
{ "Broadcom BCM57402 NetXtreme-E Dual-port 10Gb Ethernet" },
|
|
{ "Broadcom BCM57402 NetXtreme-E Dual-port 10Gb Ethernet" },
|
|
{ "Broadcom BCM57404 NetXtreme-E Dual-port 10Gb/25Gb Ethernet" },
|
|
{ "Broadcom BCM57404 NetXtreme-E Dual-port 10Gb/25Gb Ethernet" },
|
|
{ "Broadcom BCM57406 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
|
{ "Broadcom BCM57406 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
|
|
|
+ { "Broadcom BCM57404 NetXtreme-E Ethernet Partition" },
|
|
|
|
+ { "Broadcom BCM57412 NetXtreme-E Dual-port 10Gb Ethernet" },
|
|
|
|
+ { "Broadcom BCM57414 NetXtreme-E Dual-port 10Gb/25Gb Ethernet" },
|
|
|
|
+ { "Broadcom BCM57416 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
|
|
|
+ { "Broadcom BCM57417 NetXtreme-E Dual-port 10GBase-T Ethernet" },
|
|
|
|
+ { "Broadcom BCM57414 NetXtreme-E Ethernet Partition" },
|
|
{ "Broadcom BCM57314 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
|
{ "Broadcom BCM57314 NetXtreme-C Dual-port 10Gb/25Gb/40Gb/50Gb Ethernet" },
|
|
{ "Broadcom BCM57304 NetXtreme-C Ethernet Virtual Function" },
|
|
{ "Broadcom BCM57304 NetXtreme-C Ethernet Virtual Function" },
|
|
{ "Broadcom BCM57404 NetXtreme-E Ethernet Virtual Function" },
|
|
{ "Broadcom BCM57404 NetXtreme-E Ethernet Virtual Function" },
|
|
|
|
+ { "Broadcom BCM57414 NetXtreme-E Ethernet Virtual Function" },
|
|
|
|
+ { "Broadcom BCM57314 NetXtreme-E Ethernet Virtual Function" },
|
|
};
|
|
};
|
|
|
|
|
|
static const struct pci_device_id bnxt_pci_tbl[] = {
|
|
static const struct pci_device_id bnxt_pci_tbl[] = {
|
|
{ PCI_VDEVICE(BROADCOM, 0x16c8), .driver_data = BCM57301 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16c8), .driver_data = BCM57301 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16c9), .driver_data = BCM57302 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16c9), .driver_data = BCM57302 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16ca), .driver_data = BCM57304 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16ca), .driver_data = BCM57304 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16ce), .driver_data = BCM57311 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16cf), .driver_data = BCM57312 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d0), .driver_data = BCM57402 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d0), .driver_data = BCM57402 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d1), .driver_data = BCM57404 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d1), .driver_data = BCM57404 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d2), .driver_data = BCM57406 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d2), .driver_data = BCM57406 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16d4), .driver_data = BCM57404_NPAR },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16d6), .driver_data = BCM57412 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16d7), .driver_data = BCM57414 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16d8), .driver_data = BCM57416 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16d9), .driver_data = BCM57417 },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16de), .driver_data = BCM57414_NPAR },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16df), .driver_data = BCM57314 },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16df), .driver_data = BCM57314 },
|
|
#ifdef CONFIG_BNXT_SRIOV
|
|
#ifdef CONFIG_BNXT_SRIOV
|
|
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = BCM57304_VF },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = BCM57304_VF },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = BCM57404_VF },
|
|
{ PCI_VDEVICE(BROADCOM, 0x16d3), .driver_data = BCM57404_VF },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16dc), .driver_data = BCM57414_VF },
|
|
|
|
+ { PCI_VDEVICE(BROADCOM, 0x16e1), .driver_data = BCM57314_VF },
|
|
#endif
|
|
#endif
|
|
{ 0 }
|
|
{ 0 }
|
|
};
|
|
};
|
|
@@ -125,12 +155,14 @@ static const u16 bnxt_async_events_arr[] = {
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED,
|
|
|
|
+ HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE,
|
|
HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE,
|
|
};
|
|
};
|
|
|
|
|
|
static bool bnxt_vf_pciid(enum board_idx idx)
|
|
static bool bnxt_vf_pciid(enum board_idx idx)
|
|
{
|
|
{
|
|
- return (idx == BCM57304_VF || idx == BCM57404_VF);
|
|
|
|
|
|
+ return (idx == BCM57304_VF || idx == BCM57404_VF ||
|
|
|
|
+ idx == BCM57314_VF || idx == BCM57414_VF);
|
|
}
|
|
}
|
|
|
|
|
|
#define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID)
|
|
#define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID)
|
|
@@ -920,6 +952,7 @@ static void bnxt_tpa_start(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
|
|
}
|
|
}
|
|
tpa_info->flags2 = le32_to_cpu(tpa_start1->rx_tpa_start_cmp_flags2);
|
|
tpa_info->flags2 = le32_to_cpu(tpa_start1->rx_tpa_start_cmp_flags2);
|
|
tpa_info->metadata = le32_to_cpu(tpa_start1->rx_tpa_start_cmp_metadata);
|
|
tpa_info->metadata = le32_to_cpu(tpa_start1->rx_tpa_start_cmp_metadata);
|
|
|
|
+ tpa_info->hdr_info = le32_to_cpu(tpa_start1->rx_tpa_start_cmp_hdr_info);
|
|
|
|
|
|
rxr->rx_prod = NEXT_RX(prod);
|
|
rxr->rx_prod = NEXT_RX(prod);
|
|
cons = NEXT_RX(cons);
|
|
cons = NEXT_RX(cons);
|
|
@@ -938,32 +971,102 @@ static void bnxt_abort_tpa(struct bnxt *bp, struct bnxt_napi *bnapi,
|
|
bnxt_reuse_rx_agg_bufs(bnapi, cp_cons, agg_bufs);
|
|
bnxt_reuse_rx_agg_bufs(bnapi, cp_cons, agg_bufs);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static struct sk_buff *bnxt_gro_func_5731x(struct bnxt_tpa_info *tpa_info,
|
|
|
|
+ int payload_off, int tcp_ts,
|
|
|
|
+ struct sk_buff *skb)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_INET
|
|
|
|
+ struct tcphdr *th;
|
|
|
|
+ int len, nw_off;
|
|
|
|
+ u16 outer_ip_off, inner_ip_off, inner_mac_off;
|
|
|
|
+ u32 hdr_info = tpa_info->hdr_info;
|
|
|
|
+ bool loopback = false;
|
|
|
|
+
|
|
|
|
+ inner_ip_off = BNXT_TPA_INNER_L3_OFF(hdr_info);
|
|
|
|
+ inner_mac_off = BNXT_TPA_INNER_L2_OFF(hdr_info);
|
|
|
|
+ outer_ip_off = BNXT_TPA_OUTER_L3_OFF(hdr_info);
|
|
|
|
+
|
|
|
|
+ /* If the packet is an internal loopback packet, the offsets will
|
|
|
|
+ * have an extra 4 bytes.
|
|
|
|
+ */
|
|
|
|
+ if (inner_mac_off == 4) {
|
|
|
|
+ loopback = true;
|
|
|
|
+ } else if (inner_mac_off > 4) {
|
|
|
|
+ __be16 proto = *((__be16 *)(skb->data + inner_ip_off -
|
|
|
|
+ ETH_HLEN - 2));
|
|
|
|
+
|
|
|
|
+ /* We only support inner iPv4/ipv6. If we don't see the
|
|
|
|
+ * correct protocol ID, it must be a loopback packet where
|
|
|
|
+ * the offsets are off by 4.
|
|
|
|
+ */
|
|
|
|
+ if (proto != htons(ETH_P_IP) && proto && htons(ETH_P_IPV6))
|
|
|
|
+ loopback = true;
|
|
|
|
+ }
|
|
|
|
+ if (loopback) {
|
|
|
|
+ /* internal loopback packet, subtract all offsets by 4 */
|
|
|
|
+ inner_ip_off -= 4;
|
|
|
|
+ inner_mac_off -= 4;
|
|
|
|
+ outer_ip_off -= 4;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ nw_off = inner_ip_off - ETH_HLEN;
|
|
|
|
+ skb_set_network_header(skb, nw_off);
|
|
|
|
+ if (tpa_info->flags2 & RX_TPA_START_CMP_FLAGS2_IP_TYPE) {
|
|
|
|
+ struct ipv6hdr *iph = ipv6_hdr(skb);
|
|
|
|
+
|
|
|
|
+ skb_set_transport_header(skb, nw_off + sizeof(struct ipv6hdr));
|
|
|
|
+ len = skb->len - skb_transport_offset(skb);
|
|
|
|
+ th = tcp_hdr(skb);
|
|
|
|
+ th->check = ~tcp_v6_check(len, &iph->saddr, &iph->daddr, 0);
|
|
|
|
+ } else {
|
|
|
|
+ struct iphdr *iph = ip_hdr(skb);
|
|
|
|
+
|
|
|
|
+ skb_set_transport_header(skb, nw_off + sizeof(struct iphdr));
|
|
|
|
+ len = skb->len - skb_transport_offset(skb);
|
|
|
|
+ th = tcp_hdr(skb);
|
|
|
|
+ th->check = ~tcp_v4_check(len, iph->saddr, iph->daddr, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (inner_mac_off) { /* tunnel */
|
|
|
|
+ struct udphdr *uh = NULL;
|
|
|
|
+ __be16 proto = *((__be16 *)(skb->data + outer_ip_off -
|
|
|
|
+ ETH_HLEN - 2));
|
|
|
|
+
|
|
|
|
+ if (proto == htons(ETH_P_IP)) {
|
|
|
|
+ struct iphdr *iph = (struct iphdr *)skb->data;
|
|
|
|
+
|
|
|
|
+ if (iph->protocol == IPPROTO_UDP)
|
|
|
|
+ uh = (struct udphdr *)(iph + 1);
|
|
|
|
+ } else {
|
|
|
|
+ struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
|
|
|
|
+
|
|
|
|
+ if (iph->nexthdr == IPPROTO_UDP)
|
|
|
|
+ uh = (struct udphdr *)(iph + 1);
|
|
|
|
+ }
|
|
|
|
+ if (uh) {
|
|
|
|
+ if (uh->check)
|
|
|
|
+ skb_shinfo(skb)->gso_type |=
|
|
|
|
+ SKB_GSO_UDP_TUNNEL_CSUM;
|
|
|
|
+ else
|
|
|
|
+ skb_shinfo(skb)->gso_type |= SKB_GSO_UDP_TUNNEL;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ return skb;
|
|
|
|
+}
|
|
|
|
+
|
|
#define BNXT_IPV4_HDR_SIZE (sizeof(struct iphdr) + sizeof(struct tcphdr))
|
|
#define BNXT_IPV4_HDR_SIZE (sizeof(struct iphdr) + sizeof(struct tcphdr))
|
|
#define BNXT_IPV6_HDR_SIZE (sizeof(struct ipv6hdr) + sizeof(struct tcphdr))
|
|
#define BNXT_IPV6_HDR_SIZE (sizeof(struct ipv6hdr) + sizeof(struct tcphdr))
|
|
|
|
|
|
-static inline struct sk_buff *bnxt_gro_skb(struct bnxt_tpa_info *tpa_info,
|
|
|
|
- struct rx_tpa_end_cmp *tpa_end,
|
|
|
|
- struct rx_tpa_end_cmp_ext *tpa_end1,
|
|
|
|
|
|
+static struct sk_buff *bnxt_gro_func_5730x(struct bnxt_tpa_info *tpa_info,
|
|
|
|
+ int payload_off, int tcp_ts,
|
|
struct sk_buff *skb)
|
|
struct sk_buff *skb)
|
|
{
|
|
{
|
|
#ifdef CONFIG_INET
|
|
#ifdef CONFIG_INET
|
|
struct tcphdr *th;
|
|
struct tcphdr *th;
|
|
- int payload_off, tcp_opt_len = 0;
|
|
|
|
- int len, nw_off;
|
|
|
|
- u16 segs;
|
|
|
|
|
|
+ int len, nw_off, tcp_opt_len;
|
|
|
|
|
|
- segs = TPA_END_TPA_SEGS(tpa_end);
|
|
|
|
- if (segs == 1)
|
|
|
|
- return skb;
|
|
|
|
-
|
|
|
|
- NAPI_GRO_CB(skb)->count = segs;
|
|
|
|
- skb_shinfo(skb)->gso_size =
|
|
|
|
- le32_to_cpu(tpa_end1->rx_tpa_end_cmp_seg_len);
|
|
|
|
- skb_shinfo(skb)->gso_type = tpa_info->gso_type;
|
|
|
|
- payload_off = (le32_to_cpu(tpa_end->rx_tpa_end_cmp_misc_v1) &
|
|
|
|
- RX_TPA_END_CMP_PAYLOAD_OFFSET) >>
|
|
|
|
- RX_TPA_END_CMP_PAYLOAD_OFFSET_SHIFT;
|
|
|
|
- if (TPA_END_GRO_TS(tpa_end))
|
|
|
|
|
|
+ if (tcp_ts)
|
|
tcp_opt_len = 12;
|
|
tcp_opt_len = 12;
|
|
|
|
|
|
if (tpa_info->gso_type == SKB_GSO_TCPV4) {
|
|
if (tpa_info->gso_type == SKB_GSO_TCPV4) {
|
|
@@ -1020,6 +1123,32 @@ static inline struct sk_buff *bnxt_gro_skb(struct bnxt_tpa_info *tpa_info,
|
|
return skb;
|
|
return skb;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline struct sk_buff *bnxt_gro_skb(struct bnxt *bp,
|
|
|
|
+ struct bnxt_tpa_info *tpa_info,
|
|
|
|
+ struct rx_tpa_end_cmp *tpa_end,
|
|
|
|
+ struct rx_tpa_end_cmp_ext *tpa_end1,
|
|
|
|
+ struct sk_buff *skb)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_INET
|
|
|
|
+ int payload_off;
|
|
|
|
+ u16 segs;
|
|
|
|
+
|
|
|
|
+ segs = TPA_END_TPA_SEGS(tpa_end);
|
|
|
|
+ if (segs == 1)
|
|
|
|
+ return skb;
|
|
|
|
+
|
|
|
|
+ NAPI_GRO_CB(skb)->count = segs;
|
|
|
|
+ skb_shinfo(skb)->gso_size =
|
|
|
|
+ le32_to_cpu(tpa_end1->rx_tpa_end_cmp_seg_len);
|
|
|
|
+ skb_shinfo(skb)->gso_type = tpa_info->gso_type;
|
|
|
|
+ payload_off = (le32_to_cpu(tpa_end->rx_tpa_end_cmp_misc_v1) &
|
|
|
|
+ RX_TPA_END_CMP_PAYLOAD_OFFSET) >>
|
|
|
|
+ RX_TPA_END_CMP_PAYLOAD_OFFSET_SHIFT;
|
|
|
|
+ skb = bp->gro_func(tpa_info, payload_off, TPA_END_GRO_TS(tpa_end), skb);
|
|
|
|
+#endif
|
|
|
|
+ return skb;
|
|
|
|
+}
|
|
|
|
+
|
|
static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
|
|
static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
|
|
struct bnxt_napi *bnapi,
|
|
struct bnxt_napi *bnapi,
|
|
u32 *raw_cons,
|
|
u32 *raw_cons,
|
|
@@ -1130,7 +1259,7 @@ static inline struct sk_buff *bnxt_tpa_end(struct bnxt *bp,
|
|
}
|
|
}
|
|
|
|
|
|
if (TPA_END_GRO(tpa_end))
|
|
if (TPA_END_GRO(tpa_end))
|
|
- skb = bnxt_gro_skb(tpa_info, tpa_end, tpa_end1, skb);
|
|
|
|
|
|
+ skb = bnxt_gro_skb(bp, tpa_info, tpa_end, tpa_end1, skb);
|
|
|
|
|
|
return skb;
|
|
return skb;
|
|
}
|
|
}
|
|
@@ -1358,6 +1487,11 @@ static int bnxt_async_event_process(struct bnxt *bp,
|
|
set_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event);
|
|
set_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE:
|
|
|
|
+ if (BNXT_PF(bp))
|
|
|
|
+ goto async_event_process_exit;
|
|
|
|
+ set_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event);
|
|
|
|
+ break;
|
|
default:
|
|
default:
|
|
netdev_err(bp->dev, "unhandled ASYNC event (id 0x%x)\n",
|
|
netdev_err(bp->dev, "unhandled ASYNC event (id 0x%x)\n",
|
|
event_id);
|
|
event_id);
|
|
@@ -2262,7 +2396,7 @@ static void bnxt_set_tpa_flags(struct bnxt *bp)
|
|
bp->flags &= ~BNXT_FLAG_TPA;
|
|
bp->flags &= ~BNXT_FLAG_TPA;
|
|
if (bp->dev->features & NETIF_F_LRO)
|
|
if (bp->dev->features & NETIF_F_LRO)
|
|
bp->flags |= BNXT_FLAG_LRO;
|
|
bp->flags |= BNXT_FLAG_LRO;
|
|
- if ((bp->dev->features & NETIF_F_GRO) && (bp->pdev->revision > 0))
|
|
|
|
|
|
+ if (bp->dev->features & NETIF_F_GRO)
|
|
bp->flags |= BNXT_FLAG_GRO;
|
|
bp->flags |= BNXT_FLAG_GRO;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3277,6 +3411,7 @@ static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
|
|
unsigned int ring = 0, grp_idx;
|
|
unsigned int ring = 0, grp_idx;
|
|
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
|
|
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
|
|
struct hwrm_vnic_cfg_input req = {0};
|
|
struct hwrm_vnic_cfg_input req = {0};
|
|
|
|
+ u16 def_vlan = 0;
|
|
|
|
|
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_CFG, -1, -1);
|
|
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_VNIC_CFG, -1, -1);
|
|
/* Only RSS support for now TBD: COS & LB */
|
|
/* Only RSS support for now TBD: COS & LB */
|
|
@@ -3297,7 +3432,11 @@ static int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id)
|
|
req.mru = cpu_to_le16(bp->dev->mtu + ETH_HLEN + ETH_FCS_LEN +
|
|
req.mru = cpu_to_le16(bp->dev->mtu + ETH_HLEN + ETH_FCS_LEN +
|
|
VLAN_HLEN);
|
|
VLAN_HLEN);
|
|
|
|
|
|
- if (bp->flags & BNXT_FLAG_STRIP_VLAN)
|
|
|
|
|
|
+#ifdef CONFIG_BNXT_SRIOV
|
|
|
|
+ if (BNXT_VF(bp))
|
|
|
|
+ def_vlan = bp->vf.vlan;
|
|
|
|
+#endif
|
|
|
|
+ if ((bp->flags & BNXT_FLAG_STRIP_VLAN) || def_vlan)
|
|
req.flags |= cpu_to_le32(VNIC_CFG_REQ_FLAGS_VLAN_STRIP_MODE);
|
|
req.flags |= cpu_to_le32(VNIC_CFG_REQ_FLAGS_VLAN_STRIP_MODE);
|
|
|
|
|
|
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
|
return hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
|
@@ -3836,6 +3975,39 @@ static int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
|
|
|
|
+{
|
|
|
|
+ struct hwrm_func_qcfg_input req = {0};
|
|
|
|
+ struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
|
|
|
|
+ int rc;
|
|
|
|
+
|
|
|
|
+ bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_FUNC_QCFG, -1, -1);
|
|
|
|
+ req.fid = cpu_to_le16(0xffff);
|
|
|
|
+ mutex_lock(&bp->hwrm_cmd_lock);
|
|
|
|
+ rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
|
|
|
|
+ if (rc)
|
|
|
|
+ goto func_qcfg_exit;
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_BNXT_SRIOV
|
|
|
|
+ if (BNXT_VF(bp)) {
|
|
|
|
+ struct bnxt_vf_info *vf = &bp->vf;
|
|
|
|
+
|
|
|
|
+ vf->vlan = le16_to_cpu(resp->vlan) & VLAN_VID_MASK;
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+ switch (resp->port_partition_type) {
|
|
|
|
+ case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_0:
|
|
|
|
+ case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_5:
|
|
|
|
+ case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR2_0:
|
|
|
|
+ bp->port_partition_type = resp->port_partition_type;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+func_qcfg_exit:
|
|
|
|
+ mutex_unlock(&bp->hwrm_cmd_lock);
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
int bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
|
int bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
|
{
|
|
{
|
|
int rc = 0;
|
|
int rc = 0;
|
|
@@ -3990,6 +4162,8 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp)
|
|
if (resp->hwrm_intf_maj >= 1)
|
|
if (resp->hwrm_intf_maj >= 1)
|
|
bp->hwrm_max_req_len = le16_to_cpu(resp->max_req_win_len);
|
|
bp->hwrm_max_req_len = le16_to_cpu(resp->max_req_win_len);
|
|
|
|
|
|
|
|
+ bp->chip_num = le16_to_cpu(resp->chip_num);
|
|
|
|
+
|
|
hwrm_ver_get_exit:
|
|
hwrm_ver_get_exit:
|
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
|
return rc;
|
|
return rc;
|
|
@@ -4230,6 +4404,11 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
|
|
netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n",
|
|
netdev_warn(bp->dev, "HWRM set coalescing failure rc: %x\n",
|
|
rc);
|
|
rc);
|
|
|
|
|
|
|
|
+ if (BNXT_VF(bp)) {
|
|
|
|
+ bnxt_hwrm_func_qcfg(bp);
|
|
|
|
+ netdev_update_features(bp->dev);
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
err_out:
|
|
err_out:
|
|
@@ -4644,6 +4823,7 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
|
|
int rc = 0;
|
|
int rc = 0;
|
|
struct hwrm_port_phy_qcaps_input req = {0};
|
|
struct hwrm_port_phy_qcaps_input req = {0};
|
|
struct hwrm_port_phy_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
|
|
struct hwrm_port_phy_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
|
|
|
|
+ struct bnxt_link_info *link_info = &bp->link_info;
|
|
|
|
|
|
if (bp->hwrm_spec_code < 0x10201)
|
|
if (bp->hwrm_spec_code < 0x10201)
|
|
return 0;
|
|
return 0;
|
|
@@ -4666,6 +4846,8 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
|
|
bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
|
|
bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
|
|
PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK;
|
|
PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK;
|
|
}
|
|
}
|
|
|
|
+ link_info->support_auto_speeds =
|
|
|
|
+ le16_to_cpu(resp->supported_speeds_auto_mode);
|
|
|
|
|
|
hwrm_phy_qcaps_exit:
|
|
hwrm_phy_qcaps_exit:
|
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
|
mutex_unlock(&bp->hwrm_cmd_lock);
|
|
@@ -4923,7 +5105,7 @@ static int bnxt_hwrm_shutdown_link(struct bnxt *bp)
|
|
{
|
|
{
|
|
struct hwrm_port_phy_cfg_input req = {0};
|
|
struct hwrm_port_phy_cfg_input req = {0};
|
|
|
|
|
|
- if (BNXT_VF(bp))
|
|
|
|
|
|
+ if (!BNXT_SINGLE_PF(bp))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
if (pci_num_vf(bp->pdev))
|
|
if (pci_num_vf(bp->pdev))
|
|
@@ -5469,7 +5651,14 @@ static netdev_features_t bnxt_fix_features(struct net_device *dev,
|
|
features |= NETIF_F_HW_VLAN_CTAG_RX |
|
|
features |= NETIF_F_HW_VLAN_CTAG_RX |
|
|
NETIF_F_HW_VLAN_STAG_RX;
|
|
NETIF_F_HW_VLAN_STAG_RX;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+#ifdef CONFIG_BNXT_SRIOV
|
|
|
|
+ if (BNXT_VF(bp)) {
|
|
|
|
+ if (bp->vf.vlan) {
|
|
|
|
+ features &= ~(NETIF_F_HW_VLAN_CTAG_RX |
|
|
|
|
+ NETIF_F_HW_VLAN_STAG_RX);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
return features;
|
|
return features;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -5585,9 +5774,10 @@ static void bnxt_dbg_dump_states(struct bnxt *bp)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-static void bnxt_reset_task(struct bnxt *bp)
|
|
|
|
|
|
+static void bnxt_reset_task(struct bnxt *bp, bool silent)
|
|
{
|
|
{
|
|
- bnxt_dbg_dump_states(bp);
|
|
|
|
|
|
+ if (!silent)
|
|
|
|
+ bnxt_dbg_dump_states(bp);
|
|
if (netif_running(bp->dev)) {
|
|
if (netif_running(bp->dev)) {
|
|
bnxt_close_nic(bp, false, false);
|
|
bnxt_close_nic(bp, false, false);
|
|
bnxt_open_nic(bp, false, false);
|
|
bnxt_open_nic(bp, false, false);
|
|
@@ -5638,6 +5828,23 @@ bnxt_restart_timer:
|
|
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
|
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* Only called from bnxt_sp_task() */
|
|
|
|
+static void bnxt_reset(struct bnxt *bp, bool silent)
|
|
|
|
+{
|
|
|
|
+ /* bnxt_reset_task() calls bnxt_close_nic() which waits
|
|
|
|
+ * for BNXT_STATE_IN_SP_TASK to clear.
|
|
|
|
+ * If there is a parallel dev_close(), bnxt_close() may be holding
|
|
|
|
+ * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear. So we
|
|
|
|
+ * must clear BNXT_STATE_IN_SP_TASK before holding rtnl().
|
|
|
|
+ */
|
|
|
|
+ clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
|
|
|
|
+ rtnl_lock();
|
|
|
|
+ if (test_bit(BNXT_STATE_OPEN, &bp->state))
|
|
|
|
+ bnxt_reset_task(bp, silent);
|
|
|
|
+ set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
|
|
|
|
+ rtnl_unlock();
|
|
|
|
+}
|
|
|
|
+
|
|
static void bnxt_cfg_ntp_filters(struct bnxt *);
|
|
static void bnxt_cfg_ntp_filters(struct bnxt *);
|
|
|
|
|
|
static void bnxt_sp_task(struct work_struct *work)
|
|
static void bnxt_sp_task(struct work_struct *work)
|
|
@@ -5674,16 +5881,11 @@ static void bnxt_sp_task(struct work_struct *work)
|
|
bnxt_hwrm_tunnel_dst_port_free(
|
|
bnxt_hwrm_tunnel_dst_port_free(
|
|
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
|
|
bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_VXLAN);
|
|
}
|
|
}
|
|
- if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) {
|
|
|
|
- /* bnxt_reset_task() calls bnxt_close_nic() which waits
|
|
|
|
- * for BNXT_STATE_IN_SP_TASK to clear.
|
|
|
|
- */
|
|
|
|
- clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
|
|
|
|
- rtnl_lock();
|
|
|
|
- bnxt_reset_task(bp);
|
|
|
|
- set_bit(BNXT_STATE_IN_SP_TASK, &bp->state);
|
|
|
|
- rtnl_unlock();
|
|
|
|
- }
|
|
|
|
|
|
+ if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event))
|
|
|
|
+ bnxt_reset(bp, false);
|
|
|
|
+
|
|
|
|
+ if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event))
|
|
|
|
+ bnxt_reset(bp, true);
|
|
|
|
|
|
if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event))
|
|
if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event))
|
|
bnxt_get_port_module_status(bp);
|
|
bnxt_get_port_module_status(bp);
|
|
@@ -6169,6 +6371,12 @@ static int bnxt_probe_phy(struct bnxt *bp)
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Older firmware does not have supported_auto_speeds, so assume
|
|
|
|
+ * that all supported speeds can be autonegotiated.
|
|
|
|
+ */
|
|
|
|
+ if (link_info->auto_link_speeds && !link_info->support_auto_speeds)
|
|
|
|
+ link_info->support_auto_speeds = link_info->support_speeds;
|
|
|
|
+
|
|
/*initialize the ethool setting copy with NVM settings */
|
|
/*initialize the ethool setting copy with NVM settings */
|
|
if (BNXT_AUTO_MODE(link_info->auto_mode)) {
|
|
if (BNXT_AUTO_MODE(link_info->auto_mode)) {
|
|
link_info->autoneg = BNXT_AUTONEG_SPEED;
|
|
link_info->autoneg = BNXT_AUTONEG_SPEED;
|
|
@@ -6342,7 +6550,13 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
goto init_err;
|
|
goto init_err;
|
|
|
|
|
|
mutex_init(&bp->hwrm_cmd_lock);
|
|
mutex_init(&bp->hwrm_cmd_lock);
|
|
- bnxt_hwrm_ver_get(bp);
|
|
|
|
|
|
+ rc = bnxt_hwrm_ver_get(bp);
|
|
|
|
+ if (rc)
|
|
|
|
+ goto init_err;
|
|
|
|
+
|
|
|
|
+ bp->gro_func = bnxt_gro_func_5730x;
|
|
|
|
+ if (BNXT_CHIP_NUM_57X1X(bp->chip_num))
|
|
|
|
+ bp->gro_func = bnxt_gro_func_5731x;
|
|
|
|
|
|
rc = bnxt_hwrm_func_drv_rgtr(bp);
|
|
rc = bnxt_hwrm_func_drv_rgtr(bp);
|
|
if (rc)
|
|
if (rc)
|
|
@@ -6365,6 +6579,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|
goto init_err;
|
|
goto init_err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ bnxt_hwrm_func_qcfg(bp);
|
|
|
|
+
|
|
bnxt_set_tpa_flags(bp);
|
|
bnxt_set_tpa_flags(bp);
|
|
bnxt_set_ring_params(bp);
|
|
bnxt_set_ring_params(bp);
|
|
if (BNXT_PF(bp))
|
|
if (BNXT_PF(bp))
|