Sun Sep 1 11:12:45 2019 UTC ()
Pull up following revision(s) (requested by msaitoh in ticket #134):

	sys/dev/pci/ixgbe/ixgbe.c: revision 1.202
	sys/dev/pci/ixgbe/ixgbe.c: revision 1.203
	sys/dev/pci/ixgbe/ixgbe.c: revision 1.204
	sys/dev/pci/ixgbe/ixv.c: revision 1.128

Simplify ix{gbe,v}_[un]register_vlan() API suggested by knakahara.

 The API was the same as FreeBSD's pre-iflib's. They use iflib now and it's
not required for us to keep the old API.
X550EM supports QSFP, so check ixgbe_media_type_fiber_qsfp too.

 An interrupt might not arrive when a module is inserted. When an link status
change interrupt occurred and the driver still regard SFP as unplugged, link
becomes up and the real media type is unknown. e.g:

 % ifconfig -m ixg0
 (snip)
         media: Ethernet autoselect (autoselect rxpause,txpause)
         status: active
         supported Ethernet media:
                 media none
                 media autoselect
 (snip)

To resolve this problem, when an link status change interrupt occurred and the
driver still regard SFP as unplugged, issue the module softint before issuing
LSC interrupt.


(martin)
diff -r1.199.2.1 -r1.199.2.2 src/sys/dev/pci/ixgbe/ixgbe.c
diff -r1.125.2.1 -r1.125.2.2 src/sys/dev/pci/ixgbe/ixv.c

cvs diff -r1.199.2.1 -r1.199.2.2 src/sys/dev/pci/ixgbe/ixgbe.c (expand / switch to unified diff)

--- src/sys/dev/pci/ixgbe/ixgbe.c 2019/09/01 11:07:05 1.199.2.1
+++ src/sys/dev/pci/ixgbe/ixgbe.c 2019/09/01 11:12:45 1.199.2.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ixgbe.c,v 1.199.2.1 2019/09/01 11:07:05 martin Exp $ */ 1/* $NetBSD: ixgbe.c,v 1.199.2.2 2019/09/01 11:12:45 martin Exp $ */
2 2
3/****************************************************************************** 3/******************************************************************************
4 4
5 Copyright (c) 2001-2017, Intel Corporation 5 Copyright (c) 2001-2017, Intel Corporation
6 All rights reserved. 6 All rights reserved.
7 7
8 Redistribution and use in source and binary forms, with or without 8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met: 9 modification, are permitted provided that the following conditions are met:
10 10
11 1. Redistributions of source code must retain the above copyright notice, 11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer. 12 this list of conditions and the following disclaimer.
13 13
14 2. Redistributions in binary form must reproduce the above copyright 14 2. Redistributions in binary form must reproduce the above copyright
@@ -212,28 +212,28 @@ static void ixgbe_enable_intr(struct ada @@ -212,28 +212,28 @@ static void ixgbe_enable_intr(struct ada
212static void ixgbe_disable_intr(struct adapter *); 212static void ixgbe_disable_intr(struct adapter *);
213static void ixgbe_update_stats_counters(struct adapter *); 213static void ixgbe_update_stats_counters(struct adapter *);
214static void ixgbe_set_promisc(struct adapter *); 214static void ixgbe_set_promisc(struct adapter *);
215static void ixgbe_set_multi(struct adapter *); 215static void ixgbe_set_multi(struct adapter *);
216static void ixgbe_update_link_status(struct adapter *); 216static void ixgbe_update_link_status(struct adapter *);
217static void ixgbe_set_ivar(struct adapter *, u8, u8, s8); 217static void ixgbe_set_ivar(struct adapter *, u8, u8, s8);
218static void ixgbe_configure_ivars(struct adapter *); 218static void ixgbe_configure_ivars(struct adapter *);
219static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); 219static u8 * ixgbe_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
220static void ixgbe_eitr_write(struct adapter *, uint32_t, uint32_t); 220static void ixgbe_eitr_write(struct adapter *, uint32_t, uint32_t);
221 221
222static void ixgbe_setup_vlan_hw_tagging(struct adapter *); 222static void ixgbe_setup_vlan_hw_tagging(struct adapter *);
223static void ixgbe_setup_vlan_hw_support(struct adapter *); 223static void ixgbe_setup_vlan_hw_support(struct adapter *);
224static int ixgbe_vlan_cb(struct ethercom *, uint16_t, bool); 224static int ixgbe_vlan_cb(struct ethercom *, uint16_t, bool);
225static int ixgbe_register_vlan(void *, struct ifnet *, u16); 225static int ixgbe_register_vlan(struct adapter *, u16);
226static int ixgbe_unregister_vlan(void *, struct ifnet *, u16); 226static int ixgbe_unregister_vlan(struct adapter *, u16);
227 227
228static void ixgbe_add_device_sysctls(struct adapter *); 228static void ixgbe_add_device_sysctls(struct adapter *);
229static void ixgbe_add_hw_stats(struct adapter *); 229static void ixgbe_add_hw_stats(struct adapter *);
230static void ixgbe_clear_evcnt(struct adapter *); 230static void ixgbe_clear_evcnt(struct adapter *);
231static int ixgbe_set_flowcntl(struct adapter *, int); 231static int ixgbe_set_flowcntl(struct adapter *, int);
232static int ixgbe_set_advertise(struct adapter *, int); 232static int ixgbe_set_advertise(struct adapter *, int);
233static int ixgbe_get_advertise(struct adapter *); 233static int ixgbe_get_advertise(struct adapter *);
234 234
235/* Sysctl handlers */ 235/* Sysctl handlers */
236static void ixgbe_set_sysctl_value(struct adapter *, const char *, 236static void ixgbe_set_sysctl_value(struct adapter *, const char *,
237 const char *, int *, int); 237 const char *, int *, int);
238static int ixgbe_sysctl_flowcntl(SYSCTLFN_PROTO); 238static int ixgbe_sysctl_flowcntl(SYSCTLFN_PROTO);
239static int ixgbe_sysctl_advertise(SYSCTLFN_PROTO); 239static int ixgbe_sysctl_advertise(SYSCTLFN_PROTO);
@@ -1479,38 +1479,35 @@ ixgbe_add_media_types(struct adapter *ad @@ -1479,38 +1479,35 @@ ixgbe_add_media_types(struct adapter *ad
1479 1479
1480/************************************************************************ 1480/************************************************************************
1481 * ixgbe_is_sfp 1481 * ixgbe_is_sfp
1482 ************************************************************************/ 1482 ************************************************************************/
1483static inline bool 1483static inline bool
1484ixgbe_is_sfp(struct ixgbe_hw *hw) 1484ixgbe_is_sfp(struct ixgbe_hw *hw)
1485{ 1485{
1486 switch (hw->mac.type) { 1486 switch (hw->mac.type) {
1487 case ixgbe_mac_82598EB: 1487 case ixgbe_mac_82598EB:
1488 if (hw->phy.type == ixgbe_phy_nl) 1488 if (hw->phy.type == ixgbe_phy_nl)
1489 return (TRUE); 1489 return (TRUE);
1490 return (FALSE); 1490 return (FALSE);
1491 case ixgbe_mac_82599EB: 1491 case ixgbe_mac_82599EB:
 1492 case ixgbe_mac_X550EM_x:
 1493 case ixgbe_mac_X550EM_a:
1492 switch (hw->mac.ops.get_media_type(hw)) { 1494 switch (hw->mac.ops.get_media_type(hw)) {
1493 case ixgbe_media_type_fiber: 1495 case ixgbe_media_type_fiber:
1494 case ixgbe_media_type_fiber_qsfp: 1496 case ixgbe_media_type_fiber_qsfp:
1495 return (TRUE); 1497 return (TRUE);
1496 default: 1498 default:
1497 return (FALSE); 1499 return (FALSE);
1498 } 1500 }
1499 case ixgbe_mac_X550EM_x: 
1500 case ixgbe_mac_X550EM_a: 
1501 if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) 
1502 return (TRUE); 
1503 return (FALSE); 
1504 default: 1501 default:
1505 return (FALSE); 1502 return (FALSE);
1506 } 1503 }
1507} /* ixgbe_is_sfp */ 1504} /* ixgbe_is_sfp */
1508 1505
1509/************************************************************************ 1506/************************************************************************
1510 * ixgbe_config_link 1507 * ixgbe_config_link
1511 ************************************************************************/ 1508 ************************************************************************/
1512static void 1509static void
1513ixgbe_config_link(struct adapter *adapter) 1510ixgbe_config_link(struct adapter *adapter)
1514{ 1511{
1515 struct ixgbe_hw *hw = &adapter->hw; 1512 struct ixgbe_hw *hw = &adapter->hw;
1516 u32 autoneg, err = 0; 1513 u32 autoneg, err = 0;
@@ -2300,92 +2297,84 @@ ixgbe_sysctl_rdt_handler(SYSCTLFN_ARGS) @@ -2300,92 +2297,84 @@ ixgbe_sysctl_rdt_handler(SYSCTLFN_ARGS)
2300 val = IXGBE_READ_REG(&adapter->hw, IXGBE_RDT(rxr->me)); 2297 val = IXGBE_READ_REG(&adapter->hw, IXGBE_RDT(rxr->me));
2301 node.sysctl_data = &val; 2298 node.sysctl_data = &val;
2302 return sysctl_lookup(SYSCTLFN_CALL(&node)); 2299 return sysctl_lookup(SYSCTLFN_CALL(&node));
2303} /* ixgbe_sysctl_rdt_handler */ 2300} /* ixgbe_sysctl_rdt_handler */
2304 2301
2305static int 2302static int
2306ixgbe_vlan_cb(struct ethercom *ec, uint16_t vid, bool set) 2303ixgbe_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
2307{ 2304{
2308 struct ifnet *ifp = &ec->ec_if; 2305 struct ifnet *ifp = &ec->ec_if;
2309 struct adapter *adapter = ifp->if_softc; 2306 struct adapter *adapter = ifp->if_softc;
2310 int rv; 2307 int rv;
2311 2308
2312 if (set) 2309 if (set)
2313 rv = ixgbe_register_vlan(ifp->if_softc, ifp, vid); 2310 rv = ixgbe_register_vlan(adapter, vid);
2314 else 2311 else
2315 rv = ixgbe_unregister_vlan(ifp->if_softc, ifp, vid); 2312 rv = ixgbe_unregister_vlan(adapter, vid);
2316 2313
2317 if (rv != 0) 2314 if (rv != 0)
2318 return rv; 2315 return rv;
2319 2316
2320 /* 2317 /*
2321 * Control VLAN HW tagging when ec_nvlan is changed from 1 to 0 2318 * Control VLAN HW tagging when ec_nvlan is changed from 1 to 0
2322 * or 0 to 1. 2319 * or 0 to 1.
2323 */ 2320 */
2324 if ((set && (ec->ec_nvlans == 1)) || (!set && (ec->ec_nvlans == 0))) 2321 if ((set && (ec->ec_nvlans == 1)) || (!set && (ec->ec_nvlans == 0)))
2325 ixgbe_setup_vlan_hw_tagging(adapter); 2322 ixgbe_setup_vlan_hw_tagging(adapter);
2326 2323
2327 return rv; 2324 return rv;
2328} 2325}
2329 2326
2330/************************************************************************ 2327/************************************************************************
2331 * ixgbe_register_vlan 2328 * ixgbe_register_vlan
2332 * 2329 *
2333 * Run via vlan config EVENT, it enables us to use the 2330 * Run via vlan config EVENT, it enables us to use the
2334 * HW Filter table since we can get the vlan id. This 2331 * HW Filter table since we can get the vlan id. This
2335 * just creates the entry in the soft version of the 2332 * just creates the entry in the soft version of the
2336 * VFTA, init will repopulate the real table. 2333 * VFTA, init will repopulate the real table.
2337 ************************************************************************/ 2334 ************************************************************************/
2338static int 2335static int
2339ixgbe_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) 2336ixgbe_register_vlan(struct adapter *adapter, u16 vtag)
2340{ 2337{
2341 struct adapter *adapter = ifp->if_softc; 
2342 u16 index, bit; 2338 u16 index, bit;
2343 int error; 2339 int error;
2344 2340
2345 if (ifp->if_softc != arg) /* Not our event */ 
2346 return EINVAL; 
2347 
2348 if ((vtag == 0) || (vtag > 4095)) /* Invalid */ 2341 if ((vtag == 0) || (vtag > 4095)) /* Invalid */
2349 return EINVAL; 2342 return EINVAL;
2350 2343
2351 IXGBE_CORE_LOCK(adapter); 2344 IXGBE_CORE_LOCK(adapter);
2352 index = (vtag >> 5) & 0x7F; 2345 index = (vtag >> 5) & 0x7F;
2353 bit = vtag & 0x1F; 2346 bit = vtag & 0x1F;
2354 adapter->shadow_vfta[index] |= ((u32)1 << bit); 2347 adapter->shadow_vfta[index] |= ((u32)1 << bit);
2355 error = adapter->hw.mac.ops.set_vfta(&adapter->hw, vtag, 0, true, 2348 error = adapter->hw.mac.ops.set_vfta(&adapter->hw, vtag, 0, true,
2356 true); 2349 true);
2357 IXGBE_CORE_UNLOCK(adapter); 2350 IXGBE_CORE_UNLOCK(adapter);
2358 if (error != 0) 2351 if (error != 0)
2359 error = EACCES; 2352 error = EACCES;
2360 2353
2361 return error; 2354 return error;
2362} /* ixgbe_register_vlan */ 2355} /* ixgbe_register_vlan */
2363 2356
2364/************************************************************************ 2357/************************************************************************
2365 * ixgbe_unregister_vlan 2358 * ixgbe_unregister_vlan
2366 * 2359 *
2367 * Run via vlan unconfig EVENT, remove our entry in the soft vfta. 2360 * Run via vlan unconfig EVENT, remove our entry in the soft vfta.
2368 ************************************************************************/ 2361 ************************************************************************/
2369static int 2362static int
2370ixgbe_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) 2363ixgbe_unregister_vlan(struct adapter *adapter, u16 vtag)
2371{ 2364{
2372 struct adapter *adapter = ifp->if_softc; 
2373 u16 index, bit; 2365 u16 index, bit;
2374 int error; 2366 int error;
2375 2367
2376 if (ifp->if_softc != arg) 
2377 return EINVAL; 
2378 
2379 if ((vtag == 0) || (vtag > 4095)) /* Invalid */ 2368 if ((vtag == 0) || (vtag > 4095)) /* Invalid */
2380 return EINVAL; 2369 return EINVAL;
2381 2370
2382 IXGBE_CORE_LOCK(adapter); 2371 IXGBE_CORE_LOCK(adapter);
2383 index = (vtag >> 5) & 0x7F; 2372 index = (vtag >> 5) & 0x7F;
2384 bit = vtag & 0x1F; 2373 bit = vtag & 0x1F;
2385 adapter->shadow_vfta[index] &= ~((u32)1 << bit); 2374 adapter->shadow_vfta[index] &= ~((u32)1 << bit);
2386 error = adapter->hw.mac.ops.set_vfta(&adapter->hw, vtag, 0, false, 2375 error = adapter->hw.mac.ops.set_vfta(&adapter->hw, vtag, 0, false,
2387 true); 2376 true);
2388 IXGBE_CORE_UNLOCK(adapter); 2377 IXGBE_CORE_UNLOCK(adapter);
2389 if (error != 0) 2378 if (error != 0)
2390 error = EACCES; 2379 error = EACCES;
2391 2380
@@ -3114,26 +3103,54 @@ ixgbe_msix_link(void *arg) @@ -3114,26 +3103,54 @@ ixgbe_msix_link(void *arg)
3114 /* First get the cause */ 3103 /* First get the cause */
3115 /* 3104 /*
3116 * The specifications of 82598, 82599, X540 and X550 say EICS register 3105 * The specifications of 82598, 82599, X540 and X550 say EICS register
3117 * is write only. However, Linux says it is a workaround for silicon 3106 * is write only. However, Linux says it is a workaround for silicon
3118 * errata to read EICS instead of EICR to get interrupt cause. It seems 3107 * errata to read EICS instead of EICR to get interrupt cause. It seems
3119 * there is a problem about read clear mechanism for EICR register. 3108 * there is a problem about read clear mechanism for EICR register.
3120 */ 3109 */
3121 eicr = IXGBE_READ_REG(hw, IXGBE_EICS); 3110 eicr = IXGBE_READ_REG(hw, IXGBE_EICS);
3122 /* Be sure the queue bits are not cleared */ 3111 /* Be sure the queue bits are not cleared */
3123 eicr &= ~IXGBE_EICR_RTX_QUEUE; 3112 eicr &= ~IXGBE_EICR_RTX_QUEUE;
3124 /* Clear interrupt with write */ 3113 /* Clear interrupt with write */
3125 IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr); 3114 IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr);
3126 3115
 3116 if (ixgbe_is_sfp(hw)) {
 3117 /* Pluggable optics-related interrupt */
 3118 if (hw->mac.type >= ixgbe_mac_X540)
 3119 eicr_mask = IXGBE_EICR_GPI_SDP0_X540;
 3120 else
 3121 eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw);
 3122
 3123 /*
 3124 * An interrupt might not arrive when a module is inserted.
 3125 * When an link status change interrupt occurred and the driver
 3126 * still regard SFP as unplugged, issue the module softint
 3127 * and then issue LSC interrupt.
 3128 */
 3129 if ((eicr & eicr_mask)
 3130 || ((hw->phy.sfp_type == ixgbe_sfp_type_not_present)
 3131 && (eicr & IXGBE_EICR_LSC))) {
 3132 IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask);
 3133 softint_schedule(adapter->mod_si);
 3134 }
 3135
 3136 if ((hw->mac.type == ixgbe_mac_82599EB) &&
 3137 (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) {
 3138 IXGBE_WRITE_REG(hw, IXGBE_EICR,
 3139 IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
 3140 softint_schedule(adapter->msf_si);
 3141 }
 3142 }
 3143
3127 /* Link status change */ 3144 /* Link status change */
3128 if (eicr & IXGBE_EICR_LSC) { 3145 if (eicr & IXGBE_EICR_LSC) {
3129 IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); 3146 IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
3130 softint_schedule(adapter->link_si); 3147 softint_schedule(adapter->link_si);
3131 } 3148 }
3132 3149
3133 if (adapter->hw.mac.type != ixgbe_mac_82598EB) { 3150 if (adapter->hw.mac.type != ixgbe_mac_82598EB) {
3134 if ((adapter->feat_en & IXGBE_FEATURE_FDIR) && 3151 if ((adapter->feat_en & IXGBE_FEATURE_FDIR) &&
3135 (eicr & IXGBE_EICR_FLOW_DIR)) { 3152 (eicr & IXGBE_EICR_FLOW_DIR)) {
3136 /* This is probably overkill :) */ 3153 /* This is probably overkill :) */
3137 if (!atomic_cas_uint(&adapter->fdir_reinit, 0, 1)) 3154 if (!atomic_cas_uint(&adapter->fdir_reinit, 0, 1))
3138 return 1; 3155 return 1;
3139 /* Disable the interrupt */ 3156 /* Disable the interrupt */
@@ -3172,46 +3189,26 @@ ixgbe_msix_link(void *arg) @@ -3172,46 +3189,26 @@ ixgbe_msix_link(void *arg)
3172 device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n"); 3189 device_printf(adapter->dev, "CRITICAL: OVER TEMP!! PHY IS SHUT DOWN!!\n");
3173 device_printf(adapter->dev, "System shutdown required!\n"); 3190 device_printf(adapter->dev, "System shutdown required!\n");
3174 IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS); 3191 IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_TS);
3175 break; 3192 break;
3176 } 3193 }
3177 } 3194 }
3178 3195
3179 /* Check for VF message */ 3196 /* Check for VF message */
3180 if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) && 3197 if ((adapter->feat_en & IXGBE_FEATURE_SRIOV) &&
3181 (eicr & IXGBE_EICR_MAILBOX)) 3198 (eicr & IXGBE_EICR_MAILBOX))
3182 softint_schedule(adapter->mbx_si); 3199 softint_schedule(adapter->mbx_si);
3183 } 3200 }
3184 3201
3185 if (ixgbe_is_sfp(hw)) { 
3186 /* Pluggable optics-related interrupt */ 
3187 if (hw->mac.type >= ixgbe_mac_X540) 
3188 eicr_mask = IXGBE_EICR_GPI_SDP0_X540; 
3189 else 
3190 eicr_mask = IXGBE_EICR_GPI_SDP2_BY_MAC(hw); 
3191 
3192 if (eicr & eicr_mask) { 
3193 IXGBE_WRITE_REG(hw, IXGBE_EICR, eicr_mask); 
3194 softint_schedule(adapter->mod_si); 
3195 } 
3196 
3197 if ((hw->mac.type == ixgbe_mac_82599EB) && 
3198 (eicr & IXGBE_EICR_GPI_SDP1_BY_MAC(hw))) { 
3199 IXGBE_WRITE_REG(hw, IXGBE_EICR, 
3200 IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); 
3201 softint_schedule(adapter->msf_si); 
3202 } 
3203 } 
3204 
3205 /* Check for fan failure */ 3202 /* Check for fan failure */
3206 if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) { 3203 if (adapter->feat_en & IXGBE_FEATURE_FAN_FAIL) {
3207 ixgbe_check_fan_failure(adapter, eicr, TRUE); 3204 ixgbe_check_fan_failure(adapter, eicr, TRUE);
3208 IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw)); 3205 IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1_BY_MAC(hw));
3209 } 3206 }
3210 3207
3211 /* External PHY interrupt */ 3208 /* External PHY interrupt */
3212 if ((hw->phy.type == ixgbe_phy_x550em_ext_t) && 3209 if ((hw->phy.type == ixgbe_phy_x550em_ext_t) &&
3213 (eicr & IXGBE_EICR_GPI_SDP0_X540)) { 3210 (eicr & IXGBE_EICR_GPI_SDP0_X540)) {
3214 IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540); 3211 IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0_X540);
3215 softint_schedule(adapter->phy_si); 3212 softint_schedule(adapter->phy_si);
3216 } 3213 }
3217 3214

cvs diff -r1.125.2.1 -r1.125.2.2 src/sys/dev/pci/ixgbe/ixv.c (expand / switch to unified diff)

--- src/sys/dev/pci/ixgbe/ixv.c 2019/09/01 11:07:05 1.125.2.1
+++ src/sys/dev/pci/ixgbe/ixv.c 2019/09/01 11:12:45 1.125.2.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/*$NetBSD: ixv.c,v 1.125.2.1 2019/09/01 11:07:05 martin Exp $*/ 1/*$NetBSD: ixv.c,v 1.125.2.2 2019/09/01 11:12:45 martin Exp $*/
2 2
3/****************************************************************************** 3/******************************************************************************
4 4
5 Copyright (c) 2001-2017, Intel Corporation 5 Copyright (c) 2001-2017, Intel Corporation
6 All rights reserved. 6 All rights reserved.
7 7
8 Redistribution and use in source and binary forms, with or without 8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met: 9 modification, are permitted provided that the following conditions are met:
10 10
11 1. Redistributions of source code must retain the above copyright notice, 11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer. 12 this list of conditions and the following disclaimer.
13 13
14 2. Redistributions in binary form must reproduce the above copyright 14 2. Redistributions in binary form must reproduce the above copyright
@@ -113,28 +113,28 @@ static s32 ixv_check_link(struct adapter @@ -113,28 +113,28 @@ static s32 ixv_check_link(struct adapter
113static void ixv_enable_intr(struct adapter *); 113static void ixv_enable_intr(struct adapter *);
114static void ixv_disable_intr(struct adapter *); 114static void ixv_disable_intr(struct adapter *);
115static void ixv_set_multi(struct adapter *); 115static void ixv_set_multi(struct adapter *);
116static void ixv_update_link_status(struct adapter *); 116static void ixv_update_link_status(struct adapter *);
117static int ixv_sysctl_debug(SYSCTLFN_PROTO); 117static int ixv_sysctl_debug(SYSCTLFN_PROTO);
118static void ixv_set_ivar(struct adapter *, u8, u8, s8); 118static void ixv_set_ivar(struct adapter *, u8, u8, s8);
119static void ixv_configure_ivars(struct adapter *); 119static void ixv_configure_ivars(struct adapter *);
120static u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *); 120static u8 * ixv_mc_array_itr(struct ixgbe_hw *, u8 **, u32 *);
121static void ixv_eitr_write(struct adapter *, uint32_t, uint32_t); 121static void ixv_eitr_write(struct adapter *, uint32_t, uint32_t);
122 122
123static void ixv_setup_vlan_tagging(struct adapter *); 123static void ixv_setup_vlan_tagging(struct adapter *);
124static int ixv_setup_vlan_support(struct adapter *); 124static int ixv_setup_vlan_support(struct adapter *);
125static int ixv_vlan_cb(struct ethercom *, uint16_t, bool); 125static int ixv_vlan_cb(struct ethercom *, uint16_t, bool);
126static int ixv_register_vlan(void *, struct ifnet *, u16); 126static int ixv_register_vlan(struct adapter *, u16);
127static int ixv_unregister_vlan(void *, struct ifnet *, u16); 127static int ixv_unregister_vlan(struct adapter *, u16);
128 128
129static void ixv_add_device_sysctls(struct adapter *); 129static void ixv_add_device_sysctls(struct adapter *);
130static void ixv_save_stats(struct adapter *); 130static void ixv_save_stats(struct adapter *);
131static void ixv_init_stats(struct adapter *); 131static void ixv_init_stats(struct adapter *);
132static void ixv_update_stats(struct adapter *); 132static void ixv_update_stats(struct adapter *);
133static void ixv_add_stats_sysctls(struct adapter *); 133static void ixv_add_stats_sysctls(struct adapter *);
134 134
135/* Sysctl handlers */ 135/* Sysctl handlers */
136static void ixv_set_sysctl_value(struct adapter *, const char *, 136static void ixv_set_sysctl_value(struct adapter *, const char *,
137 const char *, int *, int); 137 const char *, int *, int);
138static int ixv_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO); 138static int ixv_sysctl_interrupt_rate_handler(SYSCTLFN_PROTO);
139static int ixv_sysctl_next_to_check_handler(SYSCTLFN_PROTO); 139static int ixv_sysctl_next_to_check_handler(SYSCTLFN_PROTO);
140static int ixv_sysctl_rdh_handler(SYSCTLFN_PROTO); 140static int ixv_sysctl_rdh_handler(SYSCTLFN_PROTO);
@@ -2048,96 +2048,88 @@ ixv_setup_vlan_support(struct adapter *a @@ -2048,96 +2048,88 @@ ixv_setup_vlan_support(struct adapter *a
2048 } 2048 }
2049 } 2049 }
2050 return error; 2050 return error;
2051} /* ixv_setup_vlan_support */ 2051} /* ixv_setup_vlan_support */
2052 2052
2053static int 2053static int
2054ixv_vlan_cb(struct ethercom *ec, uint16_t vid, bool set) 2054ixv_vlan_cb(struct ethercom *ec, uint16_t vid, bool set)
2055{ 2055{
2056 struct ifnet *ifp = &ec->ec_if; 2056 struct ifnet *ifp = &ec->ec_if;
2057 struct adapter *adapter = ifp->if_softc; 2057 struct adapter *adapter = ifp->if_softc;
2058 int rv; 2058 int rv;
2059 2059
2060 if (set) 2060 if (set)
2061 rv = ixv_register_vlan(ifp->if_softc, ifp, vid); 2061 rv = ixv_register_vlan(adapter, vid);
2062 else 2062 else
2063 rv = ixv_unregister_vlan(ifp->if_softc, ifp, vid); 2063 rv = ixv_unregister_vlan(adapter, vid);
2064 2064
2065 if (rv != 0) 2065 if (rv != 0)
2066 return rv; 2066 return rv;
2067 2067
2068 /* 2068 /*
2069 * Control VLAN HW tagging when ec_nvlan is changed from 1 to 0 2069 * Control VLAN HW tagging when ec_nvlan is changed from 1 to 0
2070 * or 0 to 1. 2070 * or 0 to 1.
2071 */ 2071 */
2072 if ((set && (ec->ec_nvlans == 1)) || (!set && (ec->ec_nvlans == 0))) 2072 if ((set && (ec->ec_nvlans == 1)) || (!set && (ec->ec_nvlans == 0)))
2073 ixv_setup_vlan_tagging(adapter); 2073 ixv_setup_vlan_tagging(adapter);
2074 2074
2075 return rv; 2075 return rv;
2076} 2076}
2077 2077
2078/************************************************************************ 2078/************************************************************************
2079 * ixv_register_vlan 2079 * ixv_register_vlan
2080 * 2080 *
2081 * Run via a vlan config EVENT, it enables us to use the 2081 * Run via a vlan config EVENT, it enables us to use the
2082 * HW Filter table since we can get the vlan id. This just 2082 * HW Filter table since we can get the vlan id. This just
2083 * creates the entry in the soft version of the VFTA, init 2083 * creates the entry in the soft version of the VFTA, init
2084 * will repopulate the real table. 2084 * will repopulate the real table.
2085 ************************************************************************/ 2085 ************************************************************************/
2086static int 2086static int
2087ixv_register_vlan(void *arg, struct ifnet *ifp, u16 vtag) 2087ixv_register_vlan(struct adapter *adapter, u16 vtag)
2088{ 2088{
2089 struct adapter *adapter = ifp->if_softc; 
2090 struct ixgbe_hw *hw = &adapter->hw; 2089 struct ixgbe_hw *hw = &adapter->hw;
2091 u16 index, bit; 2090 u16 index, bit;
2092 int error; 2091 int error;
2093 2092
2094 if (ifp->if_softc != arg) /* Not our event */ 
2095 return EINVAL; 
2096 
2097 if ((vtag == 0) || (vtag > 4095)) /* Invalid */ 2093 if ((vtag == 0) || (vtag > 4095)) /* Invalid */
2098 return EINVAL; 2094 return EINVAL;
2099 IXGBE_CORE_LOCK(adapter); 2095 IXGBE_CORE_LOCK(adapter);
2100 index = (vtag >> 5) & 0x7F; 2096 index = (vtag >> 5) & 0x7F;
2101 bit = vtag & 0x1F; 2097 bit = vtag & 0x1F;
2102 adapter->shadow_vfta[index] |= ((u32)1 << bit); 2098 adapter->shadow_vfta[index] |= ((u32)1 << bit);
2103 error = hw->mac.ops.set_vfta(hw, vtag, 0, true, false); 2099 error = hw->mac.ops.set_vfta(hw, vtag, 0, true, false);
2104 IXGBE_CORE_UNLOCK(adapter); 2100 IXGBE_CORE_UNLOCK(adapter);
2105 2101
2106 if (error != 0) { 2102 if (error != 0) {
2107 device_printf(adapter->dev, "failed to register vlan %hu\n", 2103 device_printf(adapter->dev, "failed to register vlan %hu\n",
2108 vtag); 2104 vtag);
2109 error = EACCES; 2105 error = EACCES;
2110 } 2106 }
2111 return error; 2107 return error;
2112} /* ixv_register_vlan */ 2108} /* ixv_register_vlan */
2113 2109
2114/************************************************************************ 2110/************************************************************************
2115 * ixv_unregister_vlan 2111 * ixv_unregister_vlan
2116 * 2112 *
2117 * Run via a vlan unconfig EVENT, remove our entry 2113 * Run via a vlan unconfig EVENT, remove our entry
2118 * in the soft vfta. 2114 * in the soft vfta.
2119 ************************************************************************/ 2115 ************************************************************************/
2120static int 2116static int
2121ixv_unregister_vlan(void *arg, struct ifnet *ifp, u16 vtag) 2117ixv_unregister_vlan(struct adapter *adapter, u16 vtag)
2122{ 2118{
2123 struct adapter *adapter = ifp->if_softc; 
2124 struct ixgbe_hw *hw = &adapter->hw; 2119 struct ixgbe_hw *hw = &adapter->hw;
2125 u16 index, bit; 2120 u16 index, bit;
2126 int error; 2121 int error;
2127 2122
2128 if (ifp->if_softc != arg) 
2129 return EINVAL; 
2130 
2131 if ((vtag == 0) || (vtag > 4095)) /* Invalid */ 2123 if ((vtag == 0) || (vtag > 4095)) /* Invalid */
2132 return EINVAL; 2124 return EINVAL;
2133 2125
2134 IXGBE_CORE_LOCK(adapter); 2126 IXGBE_CORE_LOCK(adapter);
2135 index = (vtag >> 5) & 0x7F; 2127 index = (vtag >> 5) & 0x7F;
2136 bit = vtag & 0x1F; 2128 bit = vtag & 0x1F;
2137 adapter->shadow_vfta[index] &= ~((u32)1 << bit); 2129 adapter->shadow_vfta[index] &= ~((u32)1 << bit);
2138 error = hw->mac.ops.set_vfta(hw, vtag, 0, false, false); 2130 error = hw->mac.ops.set_vfta(hw, vtag, 0, false, false);
2139 IXGBE_CORE_UNLOCK(adapter); 2131 IXGBE_CORE_UNLOCK(adapter);
2140 2132
2141 if (error != 0) { 2133 if (error != 0) {
2142 device_printf(adapter->dev, "failed to unregister vlan %hu\n", 2134 device_printf(adapter->dev, "failed to unregister vlan %hu\n",
2143 vtag); 2135 vtag);