xref: /onnv-gate/usr/src/uts/common/io/e1000g/e1000_api.c (revision 5948:7bb4e816277f)
14919Sxy150489 /*
24919Sxy150489  * This file is provided under a CDDLv1 license.  When using or
34919Sxy150489  * redistributing this file, you may do so under this license.
44919Sxy150489  * In redistributing this file this license must be included
54919Sxy150489  * and no other modification of this header file is permitted.
64919Sxy150489  *
74919Sxy150489  * CDDL LICENSE SUMMARY
84919Sxy150489  *
94919Sxy150489  * Copyright(c) 1999 - 2007 Intel Corporation. All rights reserved.
104919Sxy150489  *
114919Sxy150489  * The contents of this file are subject to the terms of Version
124919Sxy150489  * 1.0 of the Common Development and Distribution License (the "License").
134919Sxy150489  *
144919Sxy150489  * You should have received a copy of the License with this software.
154919Sxy150489  * You can obtain a copy of the License at
164919Sxy150489  *	http://www.opensolaris.org/os/licensing.
174919Sxy150489  * See the License for the specific language governing permissions
184919Sxy150489  * and limitations under the License.
194919Sxy150489  */
204919Sxy150489 
214919Sxy150489 /*
22*5948Sml40262  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
234919Sxy150489  * Use is subject to license terms of the CDDLv1.
244919Sxy150489  */
254919Sxy150489 
264919Sxy150489 #pragma ident	"%Z%%M%	%I%	%E% SMI"
274919Sxy150489 
284919Sxy150489 /*
294919Sxy150489  * IntelVersion: HSD_2343720b_DragonLake3 v2007-06-14_HSD_2343720b_DragonLake3
304919Sxy150489  */
314919Sxy150489 #include "e1000_api.h"
324919Sxy150489 #include "e1000_mac.h"
334919Sxy150489 #include "e1000_nvm.h"
344919Sxy150489 #include "e1000_phy.h"
354919Sxy150489 
364919Sxy150489 extern void e1000_init_function_pointers_82542(struct e1000_hw *hw);
374919Sxy150489 extern void e1000_init_function_pointers_82543(struct e1000_hw *hw);
384919Sxy150489 extern void e1000_init_function_pointers_82540(struct e1000_hw *hw);
394919Sxy150489 extern void e1000_init_function_pointers_82571(struct e1000_hw *hw);
404919Sxy150489 extern void e1000_init_function_pointers_82541(struct e1000_hw *hw);
414919Sxy150489 extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw);
424919Sxy150489 extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw);
434919Sxy150489 extern void e1000_init_function_pointers_vf(struct e1000_hw *hw);
444919Sxy150489 
454919Sxy150489 /*
464919Sxy150489  * e1000_init_mac_params - Initialize MAC function pointers
474919Sxy150489  * @hw: pointer to the HW structure
484919Sxy150489  *
494919Sxy150489  * This function initializes the function pointers for the MAC
504919Sxy150489  * set of functions.  Called by drivers or by e1000_setup_init_funcs.
514919Sxy150489  */
524919Sxy150489 s32
534919Sxy150489 e1000_init_mac_params(struct e1000_hw *hw)
544919Sxy150489 {
554919Sxy150489 	s32 ret_val = E1000_SUCCESS;
564919Sxy150489 
574919Sxy150489 	if (hw->func.init_mac_params) {
584919Sxy150489 		ret_val = hw->func.init_mac_params(hw);
594919Sxy150489 		if (ret_val) {
604919Sxy150489 			DEBUGOUT("MAC Initialization Error\n");
614919Sxy150489 			goto out;
624919Sxy150489 		}
634919Sxy150489 	} else {
644919Sxy150489 		DEBUGOUT("mac.init_mac_params was NULL\n");
654919Sxy150489 		ret_val = -E1000_ERR_CONFIG;
664919Sxy150489 	}
674919Sxy150489 
684919Sxy150489 out:
694919Sxy150489 	return (ret_val);
704919Sxy150489 }
714919Sxy150489 
724919Sxy150489 /*
734919Sxy150489  * e1000_init_nvm_params - Initialize NVM function pointers
744919Sxy150489  * @hw: pointer to the HW structure
754919Sxy150489  *
764919Sxy150489  * This function initializes the function pointers for the NVM
774919Sxy150489  * set of functions.  Called by drivers or by e1000_setup_init_funcs.
784919Sxy150489  */
794919Sxy150489 s32
804919Sxy150489 e1000_init_nvm_params(struct e1000_hw *hw)
814919Sxy150489 {
824919Sxy150489 	s32 ret_val = E1000_SUCCESS;
834919Sxy150489 
844919Sxy150489 	if (hw->func.init_nvm_params) {
854919Sxy150489 		ret_val = hw->func.init_nvm_params(hw);
864919Sxy150489 		if (ret_val) {
874919Sxy150489 			DEBUGOUT("NVM Initialization Error\n");
884919Sxy150489 			goto out;
894919Sxy150489 		}
904919Sxy150489 	} else {
914919Sxy150489 		DEBUGOUT("nvm.init_nvm_params was NULL\n");
924919Sxy150489 		ret_val = -E1000_ERR_CONFIG;
934919Sxy150489 	}
944919Sxy150489 
954919Sxy150489 out:
964919Sxy150489 	return (ret_val);
974919Sxy150489 }
984919Sxy150489 
994919Sxy150489 /*
1004919Sxy150489  * e1000_init_phy_params - Initialize PHY function pointers
1014919Sxy150489  * @hw: pointer to the HW structure
1024919Sxy150489  *
1034919Sxy150489  * This function initializes the function pointers for the PHY
1044919Sxy150489  * set of functions.  Called by drivers or by e1000_setup_init_funcs.
1054919Sxy150489  */
1064919Sxy150489 s32
1074919Sxy150489 e1000_init_phy_params(struct e1000_hw *hw)
1084919Sxy150489 {
1094919Sxy150489 	s32 ret_val = E1000_SUCCESS;
1104919Sxy150489 
1114919Sxy150489 	if (hw->func.init_phy_params) {
1124919Sxy150489 		ret_val = hw->func.init_phy_params(hw);
1134919Sxy150489 		if (ret_val) {
1144919Sxy150489 			DEBUGOUT("PHY Initialization Error\n");
1154919Sxy150489 			goto out;
1164919Sxy150489 		}
1174919Sxy150489 	} else {
1184919Sxy150489 		DEBUGOUT("phy.init_phy_params was NULL\n");
1194919Sxy150489 		ret_val = -E1000_ERR_CONFIG;
1204919Sxy150489 	}
1214919Sxy150489 
1224919Sxy150489 out:
1234919Sxy150489 	return (ret_val);
1244919Sxy150489 }
1254919Sxy150489 
1264919Sxy150489 /*
1274919Sxy150489  * e1000_set_mac_type - Sets MAC type
1284919Sxy150489  * @hw: pointer to the HW structure
1294919Sxy150489  *
1304919Sxy150489  * This function sets the mac type of the adapter based on the
1314919Sxy150489  * device ID stored in the hw structure.
1324919Sxy150489  * MUST BE FIRST FUNCTION CALLED (explicitly or through
1334919Sxy150489  * e1000_setup_init_funcs()).
1344919Sxy150489  */
1354919Sxy150489 s32
1364919Sxy150489 e1000_set_mac_type(struct e1000_hw *hw)
1374919Sxy150489 {
1384919Sxy150489 	struct e1000_mac_info *mac = &hw->mac;
1394919Sxy150489 	s32 ret_val = E1000_SUCCESS;
1404919Sxy150489 
1414919Sxy150489 	DEBUGFUNC("e1000_set_mac_type");
1424919Sxy150489 
1434919Sxy150489 	switch (hw->device_id) {
1444919Sxy150489 	case E1000_DEV_ID_82542:
1454919Sxy150489 		mac->type = e1000_82542;
1464919Sxy150489 		break;
1474919Sxy150489 	case E1000_DEV_ID_82543GC_FIBER:
1484919Sxy150489 	case E1000_DEV_ID_82543GC_COPPER:
1494919Sxy150489 		mac->type = e1000_82543;
1504919Sxy150489 		break;
1514919Sxy150489 	case E1000_DEV_ID_82544EI_COPPER:
1524919Sxy150489 	case E1000_DEV_ID_82544EI_FIBER:
1534919Sxy150489 	case E1000_DEV_ID_82544GC_COPPER:
1544919Sxy150489 	case E1000_DEV_ID_82544GC_LOM:
1554919Sxy150489 		mac->type = e1000_82544;
1564919Sxy150489 		break;
1574919Sxy150489 	case E1000_DEV_ID_82540EM:
1584919Sxy150489 	case E1000_DEV_ID_82540EM_LOM:
1594919Sxy150489 	case E1000_DEV_ID_82540EP:
1604919Sxy150489 	case E1000_DEV_ID_82540EP_LOM:
1614919Sxy150489 	case E1000_DEV_ID_82540EP_LP:
1624919Sxy150489 		mac->type = e1000_82540;
1634919Sxy150489 		break;
1644919Sxy150489 	case E1000_DEV_ID_82545EM_COPPER:
1654919Sxy150489 	case E1000_DEV_ID_82545EM_FIBER:
1664919Sxy150489 		mac->type = e1000_82545;
1674919Sxy150489 		break;
1684919Sxy150489 	case E1000_DEV_ID_82545GM_COPPER:
1694919Sxy150489 	case E1000_DEV_ID_82545GM_FIBER:
1704919Sxy150489 	case E1000_DEV_ID_82545GM_SERDES:
1714919Sxy150489 		mac->type = e1000_82545_rev_3;
1724919Sxy150489 		break;
1734919Sxy150489 	case E1000_DEV_ID_82546EB_COPPER:
1744919Sxy150489 	case E1000_DEV_ID_82546EB_FIBER:
1754919Sxy150489 	case E1000_DEV_ID_82546EB_QUAD_COPPER:
1764919Sxy150489 		mac->type = e1000_82546;
1774919Sxy150489 		break;
1784919Sxy150489 	case E1000_DEV_ID_82546GB_COPPER:
1794919Sxy150489 	case E1000_DEV_ID_82546GB_FIBER:
1804919Sxy150489 	case E1000_DEV_ID_82546GB_SERDES:
1814919Sxy150489 	case E1000_DEV_ID_82546GB_PCIE:
1824919Sxy150489 	case E1000_DEV_ID_82546GB_QUAD_COPPER:
1834919Sxy150489 	case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3:
1844919Sxy150489 		mac->type = e1000_82546_rev_3;
1854919Sxy150489 		break;
1864919Sxy150489 	case E1000_DEV_ID_82541EI:
1874919Sxy150489 	case E1000_DEV_ID_82541EI_MOBILE:
1884919Sxy150489 	case E1000_DEV_ID_82541ER_LOM:
1894919Sxy150489 		mac->type = e1000_82541;
1904919Sxy150489 		break;
1914919Sxy150489 	case E1000_DEV_ID_82541ER:
1924919Sxy150489 	case E1000_DEV_ID_82541GI:
1934919Sxy150489 	case E1000_DEV_ID_82541GI_LF:
1944919Sxy150489 	case E1000_DEV_ID_82541GI_MOBILE:
1954919Sxy150489 		mac->type = e1000_82541_rev_2;
1964919Sxy150489 		break;
1974919Sxy150489 	case E1000_DEV_ID_82547EI:
1984919Sxy150489 	case E1000_DEV_ID_82547EI_MOBILE:
1994919Sxy150489 		mac->type = e1000_82547;
2004919Sxy150489 		break;
2014919Sxy150489 	case E1000_DEV_ID_82547GI:
2024919Sxy150489 		mac->type = e1000_82547_rev_2;
2034919Sxy150489 		break;
2044919Sxy150489 	case E1000_DEV_ID_82571EB_COPPER:
2054919Sxy150489 	case E1000_DEV_ID_82571EB_FIBER:
2064919Sxy150489 	case E1000_DEV_ID_82571EB_SERDES:
2074919Sxy150489 	case E1000_DEV_ID_82571EB_SERDES_DUAL:
2084919Sxy150489 	case E1000_DEV_ID_82571EB_SERDES_QUAD:
2094919Sxy150489 	case E1000_DEV_ID_82571EB_QUAD_COPPER:
2104919Sxy150489 	case E1000_DEV_ID_82571PT_QUAD_COPPER:
2114919Sxy150489 	case E1000_DEV_ID_82571EB_QUAD_FIBER:
2124919Sxy150489 	case E1000_DEV_ID_82571EB_QUAD_COPPER_LP:
2134919Sxy150489 		mac->type = e1000_82571;
2144919Sxy150489 		break;
2154919Sxy150489 	case E1000_DEV_ID_82572EI:
2164919Sxy150489 	case E1000_DEV_ID_82572EI_COPPER:
2174919Sxy150489 	case E1000_DEV_ID_82572EI_FIBER:
2184919Sxy150489 	case E1000_DEV_ID_82572EI_SERDES:
2194919Sxy150489 		mac->type = e1000_82572;
2204919Sxy150489 		break;
2214919Sxy150489 	case E1000_DEV_ID_82573E:
2224919Sxy150489 	case E1000_DEV_ID_82573E_IAMT:
2234919Sxy150489 	case E1000_DEV_ID_82573L:
2244919Sxy150489 		mac->type = e1000_82573;
2254919Sxy150489 		break;
2264919Sxy150489 	case E1000_DEV_ID_80003ES2LAN_COPPER_DPT:
2274919Sxy150489 	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
2284919Sxy150489 	case E1000_DEV_ID_80003ES2LAN_COPPER_SPT:
2294919Sxy150489 	case E1000_DEV_ID_80003ES2LAN_SERDES_SPT:
2304919Sxy150489 		mac->type = e1000_80003es2lan;
2314919Sxy150489 		break;
2324919Sxy150489 	case E1000_DEV_ID_ICH8_IFE:
2334919Sxy150489 	case E1000_DEV_ID_ICH8_IFE_GT:
2344919Sxy150489 	case E1000_DEV_ID_ICH8_IFE_G:
2354919Sxy150489 	case E1000_DEV_ID_ICH8_IGP_M:
2364919Sxy150489 	case E1000_DEV_ID_ICH8_IGP_M_AMT:
2374919Sxy150489 	case E1000_DEV_ID_ICH8_IGP_AMT:
2384919Sxy150489 	case E1000_DEV_ID_ICH8_IGP_C:
2394919Sxy150489 		mac->type = e1000_ich8lan;
2404919Sxy150489 		break;
2414919Sxy150489 	case E1000_DEV_ID_ICH9_IFE:
2424919Sxy150489 	case E1000_DEV_ID_ICH9_IFE_GT:
2434919Sxy150489 	case E1000_DEV_ID_ICH9_IFE_G:
2444919Sxy150489 	case E1000_DEV_ID_ICH9_IGP_AMT:
245*5948Sml40262 	case E1000_DEV_ID_ICH9_IGP_M:
246*5948Sml40262 	case E1000_DEV_ID_ICH9_IGP_M_AMT:
2474919Sxy150489 	case E1000_DEV_ID_ICH9_IGP_C:
2484919Sxy150489 		mac->type = e1000_ich9lan;
2494919Sxy150489 		break;
2504919Sxy150489 	default:
2514919Sxy150489 		/* Should never have loaded on this device */
2524919Sxy150489 		ret_val = -E1000_ERR_MAC_INIT;
2534919Sxy150489 		break;
2544919Sxy150489 	}
2554919Sxy150489 
2564919Sxy150489 	return (ret_val);
2574919Sxy150489 }
2584919Sxy150489 
2594919Sxy150489 /*
2604919Sxy150489  * e1000_setup_init_funcs - Initializes function pointers
2614919Sxy150489  * @hw: pointer to the HW structure
2624919Sxy150489  * @init_device: TRUE will initialize the rest of the function pointers
2634919Sxy150489  *                getting the device ready for use.  FALSE will only set
2644919Sxy150489  *                MAC type and the function pointers for the other init
2654919Sxy150489  *                functions.  Passing FALSE will not generate any hardware
2664919Sxy150489  *                reads or writes.
2674919Sxy150489  *
2684919Sxy150489  * This function must be called by a driver in order to use the rest
2694919Sxy150489  * of the 'shared' code files. Called by drivers only.
2704919Sxy150489  */
2714919Sxy150489 s32
2724919Sxy150489 e1000_setup_init_funcs(struct e1000_hw *hw, boolean_t init_device)
2734919Sxy150489 {
2744919Sxy150489 	s32 ret_val;
2754919Sxy150489 
2764919Sxy150489 	/* Can't do much good without knowing the MAC type. */
2774919Sxy150489 	ret_val = e1000_set_mac_type(hw);
2784919Sxy150489 	if (ret_val) {
2794919Sxy150489 		DEBUGOUT("ERROR: MAC type could not be set properly.\n");
2804919Sxy150489 		goto out;
2814919Sxy150489 	}
2824919Sxy150489 	if (!hw->hw_addr) {
2834919Sxy150489 		DEBUGOUT("ERROR: Registers not mapped\n");
2844919Sxy150489 		ret_val = -E1000_ERR_CONFIG;
2854919Sxy150489 		goto out;
2864919Sxy150489 	}
2874919Sxy150489 
2884919Sxy150489 	/*
2894919Sxy150489 	 * Init some generic function pointers that are currently all pointing
2904919Sxy150489 	 * to generic implementations. We do this first allowing a driver
2914919Sxy150489 	 * module to override it afterwards.
2924919Sxy150489 	 */
2934919Sxy150489 	hw->func.config_collision_dist = e1000_config_collision_dist_generic;
2944919Sxy150489 	hw->func.rar_set = e1000_rar_set_generic;
2954919Sxy150489 	hw->func.validate_mdi_setting = e1000_validate_mdi_setting_generic;
2964919Sxy150489 	hw->func.mng_host_if_write = e1000_mng_host_if_write_generic;
2974919Sxy150489 	hw->func.mng_write_cmd_header = e1000_mng_write_cmd_header_generic;
2984919Sxy150489 	hw->func.mng_enable_host_if = e1000_mng_enable_host_if_generic;
2994919Sxy150489 	hw->func.wait_autoneg = e1000_wait_autoneg_generic;
3004919Sxy150489 	hw->func.reload_nvm = e1000_reload_nvm_generic;
3014919Sxy150489 
3024919Sxy150489 	/*
3034919Sxy150489 	 * Set up the init function pointers. These are functions within the
3044919Sxy150489 	 * adapter family file that sets up function pointers for the rest of
3054919Sxy150489 	 * the functions in that family.
3064919Sxy150489 	 */
3074919Sxy150489 	switch (hw->mac.type) {
3084919Sxy150489 	case e1000_82542:
3094919Sxy150489 		e1000_init_function_pointers_82542(hw);
3104919Sxy150489 		break;
3114919Sxy150489 	case e1000_82543:
3124919Sxy150489 	case e1000_82544:
3134919Sxy150489 		e1000_init_function_pointers_82543(hw);
3144919Sxy150489 		break;
3154919Sxy150489 	case e1000_82540:
3164919Sxy150489 	case e1000_82545:
3174919Sxy150489 	case e1000_82545_rev_3:
3184919Sxy150489 	case e1000_82546:
3194919Sxy150489 	case e1000_82546_rev_3:
3204919Sxy150489 		e1000_init_function_pointers_82540(hw);
3214919Sxy150489 		break;
3224919Sxy150489 	case e1000_82541:
3234919Sxy150489 	case e1000_82541_rev_2:
3244919Sxy150489 	case e1000_82547:
3254919Sxy150489 	case e1000_82547_rev_2:
3264919Sxy150489 		e1000_init_function_pointers_82541(hw);
3274919Sxy150489 		break;
3284919Sxy150489 	case e1000_82571:
3294919Sxy150489 	case e1000_82572:
3304919Sxy150489 	case e1000_82573:
3314919Sxy150489 		e1000_init_function_pointers_82571(hw);
3324919Sxy150489 		break;
3334919Sxy150489 	case e1000_80003es2lan:
3344919Sxy150489 		e1000_init_function_pointers_80003es2lan(hw);
3354919Sxy150489 		break;
3364919Sxy150489 	case e1000_ich8lan:
3374919Sxy150489 	case e1000_ich9lan:
3384919Sxy150489 		e1000_init_function_pointers_ich8lan(hw);
3394919Sxy150489 		break;
3404919Sxy150489 	default:
3414919Sxy150489 		DEBUGOUT("Hardware not supported\n");
3424919Sxy150489 		ret_val = -E1000_ERR_CONFIG;
3434919Sxy150489 		break;
3444919Sxy150489 	}
3454919Sxy150489 
3464919Sxy150489 	/*
3474919Sxy150489 	 * Initialize the rest of the function pointers. These require some
3484919Sxy150489 	 * register reads/writes in some cases.
3494919Sxy150489 	 */
3504919Sxy150489 	if (!(ret_val) && init_device) {
3514919Sxy150489 		ret_val = e1000_init_mac_params(hw);
3524919Sxy150489 		if (ret_val)
3534919Sxy150489 			goto out;
3544919Sxy150489 
3554919Sxy150489 		ret_val = e1000_init_nvm_params(hw);
3564919Sxy150489 		if (ret_val)
3574919Sxy150489 			goto out;
3584919Sxy150489 
3594919Sxy150489 		ret_val = e1000_init_phy_params(hw);
3604919Sxy150489 		if (ret_val)
3614919Sxy150489 			goto out;
3624919Sxy150489 
3634919Sxy150489 	}
3644919Sxy150489 
3654919Sxy150489 out:
3664919Sxy150489 	return (ret_val);
3674919Sxy150489 }
3684919Sxy150489 
3694919Sxy150489 /*
3704919Sxy150489  * e1000_remove_device - Free device specific structure
3714919Sxy150489  * @hw: pointer to the HW structure
3724919Sxy150489  *
3734919Sxy150489  * If a device specific structure was allocated, this function will
3744919Sxy150489  * free it. This is a function pointer entry point called by drivers.
3754919Sxy150489  */
3764919Sxy150489 void
3774919Sxy150489 e1000_remove_device(struct e1000_hw *hw)
3784919Sxy150489 {
3794919Sxy150489 	if (hw->func.remove_device)
3804919Sxy150489 		hw->func.remove_device(hw);
3814919Sxy150489 }
3824919Sxy150489 
3834919Sxy150489 /*
3844919Sxy150489  * e1000_get_bus_info - Obtain bus information for adapter
3854919Sxy150489  * @hw: pointer to the HW structure
3864919Sxy150489  *
3874919Sxy150489  * This will obtain information about the HW bus for which the
3884919Sxy150489  * adaper is attached and stores it in the hw structure. This is a
3894919Sxy150489  * function pointer entry point called by drivers.
3904919Sxy150489  */
3914919Sxy150489 s32
3924919Sxy150489 e1000_get_bus_info(struct e1000_hw *hw)
3934919Sxy150489 {
3944919Sxy150489 	if (hw->func.get_bus_info)
3954919Sxy150489 		return (hw->func.get_bus_info(hw));
3964919Sxy150489 
3974919Sxy150489 	return (E1000_SUCCESS);
3984919Sxy150489 }
3994919Sxy150489 
4004919Sxy150489 /*
4014919Sxy150489  * e1000_clear_vfta - Clear VLAN filter table
4024919Sxy150489  * @hw: pointer to the HW structure
4034919Sxy150489  *
4044919Sxy150489  * This clears the VLAN filter table on the adapter. This is a function
4054919Sxy150489  * pointer entry point called by drivers.
4064919Sxy150489  */
4074919Sxy150489 void
4084919Sxy150489 e1000_clear_vfta(struct e1000_hw *hw)
4094919Sxy150489 {
4104919Sxy150489 	if (hw->func.clear_vfta)
4114919Sxy150489 		hw->func.clear_vfta(hw);
4124919Sxy150489 }
4134919Sxy150489 
4144919Sxy150489 /*
4154919Sxy150489  * e1000_write_vfta - Write value to VLAN filter table
4164919Sxy150489  * @hw: pointer to the HW structure
4174919Sxy150489  * @offset: the 32-bit offset in which to write the value to.
4184919Sxy150489  * @value: the 32-bit value to write at location offset.
4194919Sxy150489  *
4204919Sxy150489  * This writes a 32-bit value to a 32-bit offset in the VLAN filter
4214919Sxy150489  * table. This is a function pointer entry point called by drivers.
4224919Sxy150489  */
4234919Sxy150489 void
4244919Sxy150489 e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
4254919Sxy150489 {
4264919Sxy150489 	if (hw->func.write_vfta)
4274919Sxy150489 		hw->func.write_vfta(hw, offset, value);
4284919Sxy150489 }
4294919Sxy150489 
4304919Sxy150489 /*
4314919Sxy150489  * e1000_mc_addr_list_update - Update Multicast addresses
4324919Sxy150489  * @hw: pointer to the HW structure
4334919Sxy150489  * @mc_addr_list: array of multicast addresses to program
4344919Sxy150489  * @mc_addr_count: number of multicast addresses to program
4354919Sxy150489  * @rar_used_count: the first RAR register free to program
4364919Sxy150489  * @rar_count: total number of supported Receive Address Registers
4374919Sxy150489  *
4384919Sxy150489  * Updates the Receive Address Registers and Multicast Table Array.
4394919Sxy150489  * The caller must have a packed mc_addr_list of multicast addresses.
4404919Sxy150489  * The parameter rar_count will usually be hw->mac.rar_entry_count
4414919Sxy150489  * unless there are workarounds that change this.  Currently no func pointer
4424919Sxy150489  * exists and all implementations are handled in the generic version of this
4434919Sxy150489  * function.
4444919Sxy150489  */
4454919Sxy150489 void
4464919Sxy150489 e1000_mc_addr_list_update(struct e1000_hw *hw, u8 *mc_addr_list,
4474919Sxy150489     u32 mc_addr_count, u32 rar_used_count, u32 rar_count)
4484919Sxy150489 {
4494919Sxy150489 	if (hw->func.mc_addr_list_update)
4504919Sxy150489 		hw->func.mc_addr_list_update(hw,
4514919Sxy150489 		    mc_addr_list,
4524919Sxy150489 		    mc_addr_count,
4534919Sxy150489 		    rar_used_count,
4544919Sxy150489 		    rar_count);
4554919Sxy150489 }
4564919Sxy150489 
4574919Sxy150489 /*
4584919Sxy150489  * e1000_force_mac_fc - Force MAC flow control
4594919Sxy150489  * @hw: pointer to the HW structure
4604919Sxy150489  *
4614919Sxy150489  * Force the MAC's flow control settings. Currently no func pointer exists
4624919Sxy150489  * and all implementations are handled in the generic version of this
4634919Sxy150489  * function.
4644919Sxy150489  */
4654919Sxy150489 s32
4664919Sxy150489 e1000_force_mac_fc(struct e1000_hw *hw)
4674919Sxy150489 {
4684919Sxy150489 	return (e1000_force_mac_fc_generic(hw));
4694919Sxy150489 }
4704919Sxy150489 
4714919Sxy150489 /*
4724919Sxy150489  * e1000_check_for_link - Check/Store link connection
4734919Sxy150489  * @hw: pointer to the HW structure
4744919Sxy150489  *
4754919Sxy150489  * This checks the link condition of the adapter and stores the
4764919Sxy150489  * results in the hw->mac structure. This is a function pointer entry
4774919Sxy150489  * point called by drivers.
4784919Sxy150489  */
4794919Sxy150489 s32
4804919Sxy150489 e1000_check_for_link(struct e1000_hw *hw)
4814919Sxy150489 {
4824919Sxy150489 	if (hw->func.check_for_link)
4834919Sxy150489 		return (hw->func.check_for_link(hw));
4844919Sxy150489 
4854919Sxy150489 	return (-E1000_ERR_CONFIG);
4864919Sxy150489 }
4874919Sxy150489 
4884919Sxy150489 /*
4894919Sxy150489  * e1000_check_mng_mode - Check management mode
4904919Sxy150489  * @hw: pointer to the HW structure
4914919Sxy150489  *
4924919Sxy150489  * This checks if the adapter has manageability enabled.
4934919Sxy150489  * This is a function pointer entry point called by drivers.
4944919Sxy150489  */
4954919Sxy150489 boolean_t
4964919Sxy150489 e1000_check_mng_mode(struct e1000_hw *hw)
4974919Sxy150489 {
4984919Sxy150489 	if (hw->func.check_mng_mode)
4994919Sxy150489 		return (hw->func.check_mng_mode(hw));
5004919Sxy150489 
5014919Sxy150489 	return (FALSE);
5024919Sxy150489 }
5034919Sxy150489 
5044919Sxy150489 /*
5054919Sxy150489  * e1000_mng_write_dhcp_info - Writes DHCP info to host interface
5064919Sxy150489  * @hw: pointer to the HW structure
5074919Sxy150489  * @buffer: pointer to the host interface
5084919Sxy150489  * @length: size of the buffer
5094919Sxy150489  *
5104919Sxy150489  * Writes the DHCP information to the host interface.
5114919Sxy150489  */
5124919Sxy150489 s32
5134919Sxy150489 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 * buffer, u16 length)
5144919Sxy150489 {
5154919Sxy150489 	return (e1000_mng_write_dhcp_info_generic(hw, buffer, length));
5164919Sxy150489 }
5174919Sxy150489 
5184919Sxy150489 /*
5194919Sxy150489  * e1000_reset_hw - Reset hardware
5204919Sxy150489  * @hw: pointer to the HW structure
5214919Sxy150489  *
5224919Sxy150489  * This resets the hardware into a known state. This is a function pointer
5234919Sxy150489  * entry point called by drivers.
5244919Sxy150489  */
5254919Sxy150489 s32
5264919Sxy150489 e1000_reset_hw(struct e1000_hw *hw)
5274919Sxy150489 {
5284919Sxy150489 	if (hw->func.reset_hw)
5294919Sxy150489 		return (hw->func.reset_hw(hw));
5304919Sxy150489 
5314919Sxy150489 	return (-E1000_ERR_CONFIG);
5324919Sxy150489 }
5334919Sxy150489 
5344919Sxy150489 /*
5354919Sxy150489  * e1000_init_hw - Initialize hardware
5364919Sxy150489  * @hw: pointer to the HW structure
5374919Sxy150489  *
5384919Sxy150489  * This inits the hardware readying it for operation. This is a function
5394919Sxy150489  * pointer entry point called by drivers.
5404919Sxy150489  */
5414919Sxy150489 s32
5424919Sxy150489 e1000_init_hw(struct e1000_hw *hw)
5434919Sxy150489 {
5444919Sxy150489 	if (hw->func.init_hw)
5454919Sxy150489 		return (hw->func.init_hw(hw));
5464919Sxy150489 
5474919Sxy150489 	return (-E1000_ERR_CONFIG);
5484919Sxy150489 }
5494919Sxy150489 
5504919Sxy150489 /*
5514919Sxy150489  * e1000_setup_link - Configures link and flow control
5524919Sxy150489  * @hw: pointer to the HW structure
5534919Sxy150489  *
5544919Sxy150489  * This configures link and flow control settings for the adapter. This
5554919Sxy150489  * is a function pointer entry point called by drivers. While modules can
5564919Sxy150489  * also call this, they probably call their own version of this function.
5574919Sxy150489  */
5584919Sxy150489 s32
5594919Sxy150489 e1000_setup_link(struct e1000_hw *hw)
5604919Sxy150489 {
5614919Sxy150489 	if (hw->func.setup_link)
5624919Sxy150489 		return (hw->func.setup_link(hw));
5634919Sxy150489 
5644919Sxy150489 	return (-E1000_ERR_CONFIG);
5654919Sxy150489 }
5664919Sxy150489 
5674919Sxy150489 /*
5684919Sxy150489  * e1000_get_speed_and_duplex - Returns current speed and duplex
5694919Sxy150489  * @hw: pointer to the HW structure
5704919Sxy150489  * @speed: pointer to a 16-bit value to store the speed
5714919Sxy150489  * @duplex: pointer to a 16-bit value to store the duplex.
5724919Sxy150489  *
5734919Sxy150489  * This returns the speed and duplex of the adapter in the two 'out'
5744919Sxy150489  * variables passed in. This is a function pointer entry point called
5754919Sxy150489  * by drivers.
5764919Sxy150489  */
5774919Sxy150489 s32
5784919Sxy150489 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 * speed, u16 * duplex)
5794919Sxy150489 {
5804919Sxy150489 	if (hw->func.get_link_up_info)
5814919Sxy150489 		return (hw->func.get_link_up_info(hw, speed, duplex));
5824919Sxy150489 
5834919Sxy150489 	return (-E1000_ERR_CONFIG);
5844919Sxy150489 }
5854919Sxy150489 
5864919Sxy150489 /*
5874919Sxy150489  * e1000_setup_led - Configures SW controllable LED
5884919Sxy150489  * @hw: pointer to the HW structure
5894919Sxy150489  *
5904919Sxy150489  * This prepares the SW controllable LED for use and saves the current state
5914919Sxy150489  * of the LED so it can be later restored. This is a function pointer entry
5924919Sxy150489  * point called by drivers.
5934919Sxy150489  */
5944919Sxy150489 s32
5954919Sxy150489 e1000_setup_led(struct e1000_hw *hw)
5964919Sxy150489 {
5974919Sxy150489 	if (hw->func.setup_led)
5984919Sxy150489 		return (hw->func.setup_led(hw));
5994919Sxy150489 
6004919Sxy150489 	return (E1000_SUCCESS);
6014919Sxy150489 }
6024919Sxy150489 
6034919Sxy150489 /*
6044919Sxy150489  * e1000_cleanup_led - Restores SW controllable LED
6054919Sxy150489  * @hw: pointer to the HW structure
6064919Sxy150489  *
6074919Sxy150489  * This restores the SW controllable LED to the value saved off by
6084919Sxy150489  * e1000_setup_led. This is a function pointer entry point called by drivers.
6094919Sxy150489  */
6104919Sxy150489 s32
6114919Sxy150489 e1000_cleanup_led(struct e1000_hw *hw)
6124919Sxy150489 {
6134919Sxy150489 	if (hw->func.cleanup_led)
6144919Sxy150489 		return (hw->func.cleanup_led(hw));
6154919Sxy150489 
6164919Sxy150489 	return (E1000_SUCCESS);
6174919Sxy150489 }
6184919Sxy150489 
6194919Sxy150489 /*
6204919Sxy150489  * e1000_blink_led - Blink SW controllable LED
6214919Sxy150489  * @hw: pointer to the HW structure
6224919Sxy150489  *
6234919Sxy150489  * This starts the adapter LED blinking. Request the LED to be setup first
6244919Sxy150489  * and cleaned up after. This is a function pointer entry point called by
6254919Sxy150489  * drivers.
6264919Sxy150489  */
6274919Sxy150489 s32
6284919Sxy150489 e1000_blink_led(struct e1000_hw *hw)
6294919Sxy150489 {
6304919Sxy150489 	if (hw->func.blink_led)
6314919Sxy150489 		return (hw->func.blink_led(hw));
6324919Sxy150489 
6334919Sxy150489 	return (E1000_SUCCESS);
6344919Sxy150489 }
6354919Sxy150489 
6364919Sxy150489 /*
6374919Sxy150489  * e1000_led_on - Turn on SW controllable LED
6384919Sxy150489  * @hw: pointer to the HW structure
6394919Sxy150489  *
6404919Sxy150489  * Turns the SW defined LED on. This is a function pointer entry point
6414919Sxy150489  * called by drivers.
6424919Sxy150489  */
6434919Sxy150489 s32
6444919Sxy150489 e1000_led_on(struct e1000_hw *hw)
6454919Sxy150489 {
6464919Sxy150489 	if (hw->func.led_on)
6474919Sxy150489 		return (hw->func.led_on(hw));
6484919Sxy150489 
6494919Sxy150489 	return (E1000_SUCCESS);
6504919Sxy150489 }
6514919Sxy150489 
6524919Sxy150489 /*
6534919Sxy150489  * e1000_led_off - Turn off SW controllable LED
6544919Sxy150489  * @hw: pointer to the HW structure
6554919Sxy150489  *
6564919Sxy150489  * Turns the SW defined LED off. This is a function pointer entry point
6574919Sxy150489  * called by drivers.
6584919Sxy150489  */
6594919Sxy150489 s32
6604919Sxy150489 e1000_led_off(struct e1000_hw *hw)
6614919Sxy150489 {
6624919Sxy150489 	if (hw->func.led_off)
6634919Sxy150489 		return (hw->func.led_off(hw));
6644919Sxy150489 
6654919Sxy150489 	return (E1000_SUCCESS);
6664919Sxy150489 }
6674919Sxy150489 
6684919Sxy150489 /*
6694919Sxy150489  * e1000_reset_adaptive - Reset adaptive IFS
6704919Sxy150489  * @hw: pointer to the HW structure
6714919Sxy150489  *
6724919Sxy150489  * Resets the adaptive IFS. Currently no func pointer exists and all
6734919Sxy150489  * implementations are handled in the generic version of this function.
6744919Sxy150489  */
6754919Sxy150489 void
6764919Sxy150489 e1000_reset_adaptive(struct e1000_hw *hw)
6774919Sxy150489 {
6784919Sxy150489 	e1000_reset_adaptive_generic(hw);
6794919Sxy150489 }
6804919Sxy150489 
6814919Sxy150489 /*
6824919Sxy150489  * e1000_update_adaptive - Update adaptive IFS
6834919Sxy150489  * @hw: pointer to the HW structure
6844919Sxy150489  *
6854919Sxy150489  * Updates adapter IFS. Currently no func pointer exists and all
6864919Sxy150489  * implementations are handled in the generic version of this function.
6874919Sxy150489  */
6884919Sxy150489 void
6894919Sxy150489 e1000_update_adaptive(struct e1000_hw *hw)
6904919Sxy150489 {
6914919Sxy150489 	e1000_update_adaptive_generic(hw);
6924919Sxy150489 }
6934919Sxy150489 
6944919Sxy150489 /*
6954919Sxy150489  * e1000_disable_pcie_master - Disable PCI-Express master access
6964919Sxy150489  * @hw: pointer to the HW structure
6974919Sxy150489  *
6984919Sxy150489  * Disables PCI-Express master access and verifies there are no pending
6994919Sxy150489  * requests. Currently no func pointer exists and all implementations are
7004919Sxy150489  * handled in the generic version of this function.
7014919Sxy150489  */
7024919Sxy150489 s32
7034919Sxy150489 e1000_disable_pcie_master(struct e1000_hw *hw)
7044919Sxy150489 {
7054919Sxy150489 	return (e1000_disable_pcie_master_generic(hw));
7064919Sxy150489 }
7074919Sxy150489 
7084919Sxy150489 /*
7094919Sxy150489  * e1000_config_collision_dist - Configure collision distance
7104919Sxy150489  * @hw: pointer to the HW structure
7114919Sxy150489  *
7124919Sxy150489  * Configures the collision distance to the default value and is used
7134919Sxy150489  * during link setup.
7144919Sxy150489  */
7154919Sxy150489 void
7164919Sxy150489 e1000_config_collision_dist(struct e1000_hw *hw)
7174919Sxy150489 {
7184919Sxy150489 	if (hw->func.config_collision_dist)
7194919Sxy150489 		hw->func.config_collision_dist(hw);
7204919Sxy150489 }
7214919Sxy150489 
7224919Sxy150489 /*
7234919Sxy150489  * e1000_rar_set - Sets a receive address register
7244919Sxy150489  * @hw: pointer to the HW structure
7254919Sxy150489  * @addr: address to set the RAR to
7264919Sxy150489  * @index: the RAR to set
7274919Sxy150489  *
7284919Sxy150489  * Sets a Receive Address Register (RAR) to the specified address.
7294919Sxy150489  */
7304919Sxy150489 void
7314919Sxy150489 e1000_rar_set(struct e1000_hw *hw, u8 * addr, u32 index)
7324919Sxy150489 {
7334919Sxy150489 	if (hw->func.rar_set)
7344919Sxy150489 		hw->func.rar_set(hw, addr, index);
7354919Sxy150489 }
7364919Sxy150489 
7374919Sxy150489 /*
7384919Sxy150489  * e1000_validate_mdi_setting - Ensures valid MDI/MDIX SW state
7394919Sxy150489  * @hw: pointer to the HW structure
7404919Sxy150489  *
7414919Sxy150489  * Ensures that the MDI/MDIX SW state is valid.
7424919Sxy150489  */
7434919Sxy150489 s32
7444919Sxy150489 e1000_validate_mdi_setting(struct e1000_hw *hw)
7454919Sxy150489 {
7464919Sxy150489 	if (hw->func.validate_mdi_setting)
7474919Sxy150489 		return (hw->func.validate_mdi_setting(hw));
7484919Sxy150489 
7494919Sxy150489 	return (E1000_SUCCESS);
7504919Sxy150489 }
7514919Sxy150489 
7524919Sxy150489 /*
7534919Sxy150489  * e1000_mta_set - Sets multicast table bit
7544919Sxy150489  * @hw: pointer to the HW structure
7554919Sxy150489  * @hash_value: Multicast hash value.
7564919Sxy150489  *
7574919Sxy150489  * This sets the bit in the multicast table corresponding to the
7584919Sxy150489  * hash value.  This is a function pointer entry point called by drivers.
7594919Sxy150489  */
7604919Sxy150489 void
7614919Sxy150489 e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
7624919Sxy150489 {
7634919Sxy150489 	if (hw->func.mta_set)
7644919Sxy150489 		hw->func.mta_set(hw, hash_value);
7654919Sxy150489 }
7664919Sxy150489 
7674919Sxy150489 /*
7684919Sxy150489  * e1000_hash_mc_addr - Determines address location in multicast table
7694919Sxy150489  * @hw: pointer to the HW structure
7704919Sxy150489  * @mc_addr: Multicast address to hash.
7714919Sxy150489  *
7724919Sxy150489  * This hashes an address to determine its location in the multicast
7734919Sxy150489  * table. Currently no func pointer exists and all implementations
7744919Sxy150489  * are handled in the generic version of this function.
7754919Sxy150489  */
7764919Sxy150489 u32
7774919Sxy150489 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
7784919Sxy150489 {
7794919Sxy150489 	return (e1000_hash_mc_addr_generic(hw, mc_addr));
7804919Sxy150489 }
7814919Sxy150489 
7824919Sxy150489 /*
7834919Sxy150489  * e1000_enable_tx_pkt_filtering - Enable packet filtering on TX
7844919Sxy150489  * @hw: pointer to the HW structure
7854919Sxy150489  *
7864919Sxy150489  * Enables packet filtering on transmit packets if manageability is enabled
7874919Sxy150489  * and host interface is enabled.
7884919Sxy150489  * Currently no func pointer exists and all implementations are handled in the
7894919Sxy150489  * generic version of this function.
7904919Sxy150489  */
7914919Sxy150489 boolean_t
7924919Sxy150489 e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
7934919Sxy150489 {
7944919Sxy150489 	return (e1000_enable_tx_pkt_filtering_generic(hw));
7954919Sxy150489 }
7964919Sxy150489 
7974919Sxy150489 /*
7984919Sxy150489  * e1000_mng_host_if_write - Writes to the manageability host interface
7994919Sxy150489  * @hw: pointer to the HW structure
8004919Sxy150489  * @buffer: pointer to the host interface buffer
8014919Sxy150489  * @length: size of the buffer
8024919Sxy150489  * @offset: location in the buffer to write to
8034919Sxy150489  * @sum: sum of the data (not checksum)
8044919Sxy150489  *
8054919Sxy150489  * This function writes the buffer content at the offset given on the host if.
8064919Sxy150489  * It also does alignment considerations to do the writes in most efficient
8074919Sxy150489  * way.  Also fills up the sum of the buffer in *buffer parameter.
8084919Sxy150489  */
8094919Sxy150489 s32
8104919Sxy150489 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, u16 length,
8114919Sxy150489     u16 offset, u8 *sum)
8124919Sxy150489 {
8134919Sxy150489 	if (hw->func.mng_host_if_write)
8144919Sxy150489 		return (hw->func.mng_host_if_write(hw, buffer, length, offset,
8154919Sxy150489 		    sum));
8164919Sxy150489 
8174919Sxy150489 	return (E1000_NOT_IMPLEMENTED);
8184919Sxy150489 }
8194919Sxy150489 
8204919Sxy150489 /*
8214919Sxy150489  * e1000_mng_write_cmd_header - Writes manageability command header
8224919Sxy150489  * @hw: pointer to the HW structure
8234919Sxy150489  * @hdr: pointer to the host interface command header
8244919Sxy150489  *
8254919Sxy150489  * Writes the command header after does the checksum calculation.
8264919Sxy150489  */
8274919Sxy150489 s32
8284919Sxy150489 e1000_mng_write_cmd_header(struct e1000_hw *hw,
8294919Sxy150489     struct e1000_host_mng_command_header *hdr)
8304919Sxy150489 {
8314919Sxy150489 	if (hw->func.mng_write_cmd_header)
8324919Sxy150489 		return (hw->func.mng_write_cmd_header(hw, hdr));
8334919Sxy150489 
8344919Sxy150489 	return (E1000_NOT_IMPLEMENTED);
8354919Sxy150489 }
8364919Sxy150489 
8374919Sxy150489 /*
8384919Sxy150489  * e1000_mng_enable_host_if - Checks host interface is enabled
8394919Sxy150489  * @hw: pointer to the HW structure
8404919Sxy150489  *
8414919Sxy150489  * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND
8424919Sxy150489  *
8434919Sxy150489  * This function checks whether the HOST IF is enabled for command operaton
8444919Sxy150489  * and also checks whether the previous command is completed.  It busy waits
8454919Sxy150489  * in case of previous command is not completed.
8464919Sxy150489  */
8474919Sxy150489 s32
8484919Sxy150489 e1000_mng_enable_host_if(struct e1000_hw *hw)
8494919Sxy150489 {
8504919Sxy150489 	if (hw->func.mng_enable_host_if)
8514919Sxy150489 		return (hw->func.mng_enable_host_if(hw));
8524919Sxy150489 
8534919Sxy150489 	return (E1000_NOT_IMPLEMENTED);
8544919Sxy150489 }
8554919Sxy150489 
8564919Sxy150489 /*
8574919Sxy150489  * e1000_wait_autoneg - Waits for autonegotiation completion
8584919Sxy150489  * @hw: pointer to the HW structure
8594919Sxy150489  *
8604919Sxy150489  * Waits for autoneg to complete. Currently no func pointer exists and all
8614919Sxy150489  * implementations are handled in the generic version of this function.
8624919Sxy150489  */
8634919Sxy150489 s32
8644919Sxy150489 e1000_wait_autoneg(struct e1000_hw *hw)
8654919Sxy150489 {
8664919Sxy150489 	if (hw->func.wait_autoneg)
8674919Sxy150489 		return (hw->func.wait_autoneg(hw));
8684919Sxy150489 
8694919Sxy150489 	return (E1000_SUCCESS);
8704919Sxy150489 }
8714919Sxy150489 
8724919Sxy150489 /*
8734919Sxy150489  * e1000_check_reset_block - Verifies PHY can be reset
8744919Sxy150489  * @hw: pointer to the HW structure
8754919Sxy150489  *
8764919Sxy150489  * Checks if the PHY is in a state that can be reset or if manageability
8774919Sxy150489  * has it tied up. This is a function pointer entry point called by drivers.
8784919Sxy150489  */
8794919Sxy150489 s32
8804919Sxy150489 e1000_check_reset_block(struct e1000_hw *hw)
8814919Sxy150489 {
8824919Sxy150489 	if (hw->func.check_reset_block)
8834919Sxy150489 		return (hw->func.check_reset_block(hw));
8844919Sxy150489 
8854919Sxy150489 	return (E1000_SUCCESS);
8864919Sxy150489 }
8874919Sxy150489 
8884919Sxy150489 /*
8894919Sxy150489  * e1000_read_phy_reg - Reads PHY register
8904919Sxy150489  * @hw: pointer to the HW structure
8914919Sxy150489  * @offset: the register to read
8924919Sxy150489  * @data: the buffer to store the 16-bit read.
8934919Sxy150489  *
8944919Sxy150489  * Reads the PHY register and returns the value in data.
8954919Sxy150489  * This is a function pointer entry point called by drivers.
8964919Sxy150489  */
8974919Sxy150489 s32
8984919Sxy150489 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data)
8994919Sxy150489 {
9004919Sxy150489 	if (hw->func.read_phy_reg)
9014919Sxy150489 		return (hw->func.read_phy_reg(hw, offset, data));
9024919Sxy150489 
9034919Sxy150489 	return (E1000_SUCCESS);
9044919Sxy150489 }
9054919Sxy150489 
9064919Sxy150489 /*
9074919Sxy150489  * e1000_write_phy_reg - Writes PHY register
9084919Sxy150489  * @hw: pointer to the HW structure
9094919Sxy150489  * @offset: the register to write
9104919Sxy150489  * @data: the value to write.
9114919Sxy150489  *
9124919Sxy150489  * Writes the PHY register at offset with the value in data.
9134919Sxy150489  * This is a function pointer entry point called by drivers.
9144919Sxy150489  */
9154919Sxy150489 s32
9164919Sxy150489 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data)
9174919Sxy150489 {
9184919Sxy150489 	if (hw->func.write_phy_reg)
9194919Sxy150489 		return (hw->func.write_phy_reg(hw, offset, data));
9204919Sxy150489 
9214919Sxy150489 	return (E1000_SUCCESS);
9224919Sxy150489 }
9234919Sxy150489 
9244919Sxy150489 /*
9254919Sxy150489  * e1000_read_kmrn_reg - Reads register using Kumeran interface
9264919Sxy150489  * @hw: pointer to the HW structure
9274919Sxy150489  * @offset: the register to read
9284919Sxy150489  * @data: the location to store the 16-bit value read.
9294919Sxy150489  *
9304919Sxy150489  * Reads a register out of the Kumeran interface. Currently no func pointer
9314919Sxy150489  * exists and all implementations are handled in the generic version of
9324919Sxy150489  * this function.
9334919Sxy150489  */
9344919Sxy150489 s32
9354919Sxy150489 e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
9364919Sxy150489 {
9374919Sxy150489 	return (e1000_read_kmrn_reg_generic(hw, offset, data));
9384919Sxy150489 }
9394919Sxy150489 
9404919Sxy150489 /*
9414919Sxy150489  * e1000_write_kmrn_reg - Writes register using Kumeran interface
9424919Sxy150489  * @hw: pointer to the HW structure
9434919Sxy150489  * @offset: the register to write
9444919Sxy150489  * @data: the value to write.
9454919Sxy150489  *
9464919Sxy150489  * Writes a register to the Kumeran interface. Currently no func pointer
9474919Sxy150489  * exists and all implementations are handled in the generic version of
9484919Sxy150489  * this function.
9494919Sxy150489  */
9504919Sxy150489 s32
9514919Sxy150489 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
9524919Sxy150489 {
9534919Sxy150489 	return (e1000_write_kmrn_reg_generic(hw, offset, data));
9544919Sxy150489 }
9554919Sxy150489 
9564919Sxy150489 /*
9574919Sxy150489  * e1000_get_cable_length - Retrieves cable length estimation
9584919Sxy150489  * @hw: pointer to the HW structure
9594919Sxy150489  *
9604919Sxy150489  * This function estimates the cable length and stores them in
9614919Sxy150489  * hw->phy.min_length and hw->phy.max_length. This is a function pointer
9624919Sxy150489  * entry point called by drivers.
9634919Sxy150489  */
9644919Sxy150489 s32
9654919Sxy150489 e1000_get_cable_length(struct e1000_hw *hw)
9664919Sxy150489 {
9674919Sxy150489 	if (hw->func.get_cable_length)
9684919Sxy150489 		return (hw->func.get_cable_length(hw));
9694919Sxy150489 
9704919Sxy150489 	return (E1000_SUCCESS);
9714919Sxy150489 }
9724919Sxy150489 
9734919Sxy150489 /*
9744919Sxy150489  * e1000_get_phy_info - Retrieves PHY information from registers
9754919Sxy150489  * @hw: pointer to the HW structure
9764919Sxy150489  *
9774919Sxy150489  * This function gets some information from various PHY registers and
9784919Sxy150489  * populates hw->phy values with it. This is a function pointer entry
9794919Sxy150489  * point called by drivers.
9804919Sxy150489  */
9814919Sxy150489 s32
9824919Sxy150489 e1000_get_phy_info(struct e1000_hw *hw)
9834919Sxy150489 {
9844919Sxy150489 	if (hw->func.get_phy_info)
9854919Sxy150489 		return (hw->func.get_phy_info(hw));
9864919Sxy150489 
9874919Sxy150489 	return (E1000_SUCCESS);
9884919Sxy150489 }
9894919Sxy150489 
9904919Sxy150489 /*
9914919Sxy150489  * e1000_phy_hw_reset - Hard PHY reset
9924919Sxy150489  * @hw: pointer to the HW structure
9934919Sxy150489  *
9944919Sxy150489  * Performs a hard PHY reset. This is a function pointer entry point called
9954919Sxy150489  * by drivers.
9964919Sxy150489  */
9974919Sxy150489 s32
9984919Sxy150489 e1000_phy_hw_reset(struct e1000_hw *hw)
9994919Sxy150489 {
10004919Sxy150489 	if (hw->func.reset_phy)
10014919Sxy150489 		return (hw->func.reset_phy(hw));
10024919Sxy150489 
10034919Sxy150489 	return (E1000_SUCCESS);
10044919Sxy150489 }
10054919Sxy150489 
10064919Sxy150489 /*
10074919Sxy150489  * e1000_phy_commit - Soft PHY reset
10084919Sxy150489  * @hw: pointer to the HW structure
10094919Sxy150489  *
10104919Sxy150489  * Performs a soft PHY reset on those that apply. This is a function pointer
10114919Sxy150489  * entry point called by drivers.
10124919Sxy150489  */
10134919Sxy150489 s32
10144919Sxy150489 e1000_phy_commit(struct e1000_hw *hw)
10154919Sxy150489 {
10164919Sxy150489 	if (hw->func.commit_phy)
10174919Sxy150489 		return (hw->func.commit_phy(hw));
10184919Sxy150489 
10194919Sxy150489 	return (E1000_SUCCESS);
10204919Sxy150489 }
10214919Sxy150489 
10224919Sxy150489 /*
10234919Sxy150489  * e1000_set_d3_lplu_state - Sets low power link up state for D0
10244919Sxy150489  * @hw: pointer to the HW structure
10254919Sxy150489  * @active: boolean used to enable/disable lplu
10264919Sxy150489  *
10274919Sxy150489  * Success returns 0, Failure returns 1
10284919Sxy150489  *
10294919Sxy150489  * The low power link up (lplu) state is set to the power management level D0
10304919Sxy150489  * and SmartSpeed is disabled when active is true, else clear lplu for D0
10314919Sxy150489  * and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
10324919Sxy150489  * is used during Dx states where the power conservation is most important.
10334919Sxy150489  * During driver activity, SmartSpeed should be enabled so performance is
10344919Sxy150489  * maintained.  This is a function pointer entry point called by drivers.
10354919Sxy150489  */
10364919Sxy150489 s32
10374919Sxy150489 e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active)
10384919Sxy150489 {
10394919Sxy150489 	if (hw->func.set_d0_lplu_state)
10404919Sxy150489 		return (hw->func.set_d0_lplu_state(hw, active));
10414919Sxy150489 
10424919Sxy150489 	return (E1000_SUCCESS);
10434919Sxy150489 }
10444919Sxy150489 
10454919Sxy150489 /*
10464919Sxy150489  * e1000_set_d3_lplu_state - Sets low power link up state for D3
10474919Sxy150489  * @hw: pointer to the HW structure
10484919Sxy150489  * @active: boolean used to enable/disable lplu
10494919Sxy150489  *
10504919Sxy150489  * Success returns 0, Failure returns 1
10514919Sxy150489  *
10524919Sxy150489  * The low power link up (lplu) state is set to the power management level D3
10534919Sxy150489  * and SmartSpeed is disabled when active is true, else clear lplu for D3
10544919Sxy150489  * and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
10554919Sxy150489  * is used during Dx states where the power conservation is most important.
10564919Sxy150489  * During driver activity, SmartSpeed should be enabled so performance is
10574919Sxy150489  * maintained.  This is a function pointer entry point called by drivers.
10584919Sxy150489  */
10594919Sxy150489 s32
10604919Sxy150489 e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active)
10614919Sxy150489 {
10624919Sxy150489 	if (hw->func.set_d3_lplu_state)
10634919Sxy150489 		return (hw->func.set_d3_lplu_state(hw, active));
10644919Sxy150489 
10654919Sxy150489 	return (E1000_SUCCESS);
10664919Sxy150489 }
10674919Sxy150489 
10684919Sxy150489 /*
10694919Sxy150489  * e1000_read_mac_addr - Reads MAC address
10704919Sxy150489  * @hw: pointer to the HW structure
10714919Sxy150489  *
10724919Sxy150489  * Reads the MAC address out of the adapter and stores it in the HW structure.
10734919Sxy150489  * Currently no func pointer exists and all implementations are handled in the
10744919Sxy150489  * generic version of this function.
10754919Sxy150489  */
10764919Sxy150489 s32
10774919Sxy150489 e1000_read_mac_addr(struct e1000_hw *hw)
10784919Sxy150489 {
10794919Sxy150489 	return (e1000_read_mac_addr_generic(hw));
10804919Sxy150489 }
10814919Sxy150489 
10824919Sxy150489 /*
10834919Sxy150489  * e1000_read_part_num - Read device part number
10844919Sxy150489  * @hw: pointer to the HW structure
10854919Sxy150489  * @part_num: pointer to device part number
10864919Sxy150489  *
10874919Sxy150489  * Reads the product board assembly (PBA) number from the EEPROM and stores
10884919Sxy150489  * the value in part_num.
10894919Sxy150489  * Currently no func pointer exists and all implementations are handled in the
10904919Sxy150489  * generic version of this function.
10914919Sxy150489  */
10924919Sxy150489 s32
10934919Sxy150489 e1000_read_part_num(struct e1000_hw *hw, u32 * part_num)
10944919Sxy150489 {
10954919Sxy150489 	return (e1000_read_part_num_generic(hw, part_num));
10964919Sxy150489 }
10974919Sxy150489 
10984919Sxy150489 /*
10994919Sxy150489  * e1000_validate_nvm_checksum - Verifies NVM (EEPROM) checksum
11004919Sxy150489  * @hw: pointer to the HW structure
11014919Sxy150489  *
11024919Sxy150489  * Validates the NVM checksum is correct. This is a function pointer entry
11034919Sxy150489  * point called by drivers.
11044919Sxy150489  */
11054919Sxy150489 s32
11064919Sxy150489 e1000_validate_nvm_checksum(struct e1000_hw *hw)
11074919Sxy150489 {
11084919Sxy150489 	if (hw->func.validate_nvm)
11094919Sxy150489 		return (hw->func.validate_nvm(hw));
11104919Sxy150489 
11114919Sxy150489 	return (-E1000_ERR_CONFIG);
11124919Sxy150489 }
11134919Sxy150489 
11144919Sxy150489 /*
11154919Sxy150489  * e1000_update_nvm_checksum - Updates NVM (EEPROM) checksum
11164919Sxy150489  * @hw: pointer to the HW structure
11174919Sxy150489  *
11184919Sxy150489  * Updates the NVM checksum. Currently no func pointer exists and all
11194919Sxy150489  * implementations are handled in the generic version of this function.
11204919Sxy150489  */
11214919Sxy150489 s32
11224919Sxy150489 e1000_update_nvm_checksum(struct e1000_hw *hw)
11234919Sxy150489 {
11244919Sxy150489 	if (hw->func.update_nvm)
11254919Sxy150489 		return (hw->func.update_nvm(hw));
11264919Sxy150489 
11274919Sxy150489 	return (-E1000_ERR_CONFIG);
11284919Sxy150489 }
11294919Sxy150489 
11304919Sxy150489 /*
11314919Sxy150489  * e1000_reload_nvm - Reloads EEPROM
11324919Sxy150489  * @hw: pointer to the HW structure
11334919Sxy150489  *
11344919Sxy150489  * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the
11354919Sxy150489  * extended control register.
11364919Sxy150489  */
11374919Sxy150489 void
11384919Sxy150489 e1000_reload_nvm(struct e1000_hw *hw)
11394919Sxy150489 {
11404919Sxy150489 	if (hw->func.reload_nvm)
11414919Sxy150489 		hw->func.reload_nvm(hw);
11424919Sxy150489 }
11434919Sxy150489 
11444919Sxy150489 /*
11454919Sxy150489  * e1000_read_nvm - Reads NVM (EEPROM)
11464919Sxy150489  * @hw: pointer to the HW structure
11474919Sxy150489  * @offset: the word offset to read
11484919Sxy150489  * @words: number of 16-bit words to read
11494919Sxy150489  * @data: pointer to the properly sized buffer for the data.
11504919Sxy150489  *
11514919Sxy150489  * Reads 16-bit chunks of data from the NVM (EEPROM). This is a function
11524919Sxy150489  * pointer entry point called by drivers.
11534919Sxy150489  */
11544919Sxy150489 s32
11554919Sxy150489 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
11564919Sxy150489 {
11574919Sxy150489 	if (hw->func.read_nvm)
11584919Sxy150489 		return (hw->func.read_nvm(hw, offset, words, data));
11594919Sxy150489 
11604919Sxy150489 	return (-E1000_ERR_CONFIG);
11614919Sxy150489 }
11624919Sxy150489 
11634919Sxy150489 /*
11644919Sxy150489  * e1000_write_nvm - Writes to NVM (EEPROM)
11654919Sxy150489  * @hw: pointer to the HW structure
11664919Sxy150489  * @offset: the word offset to read
11674919Sxy150489  * @words: number of 16-bit words to write
11684919Sxy150489  * @data: pointer to the properly sized buffer for the data.
11694919Sxy150489  *
11704919Sxy150489  * Writes 16-bit chunks of data to the NVM (EEPROM). This is a function
11714919Sxy150489  * pointer entry point called by drivers.
11724919Sxy150489  */
11734919Sxy150489 s32
11744919Sxy150489 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
11754919Sxy150489 {
11764919Sxy150489 	if (hw->func.write_nvm)
11774919Sxy150489 		return (hw->func.write_nvm(hw, offset, words, data));
11784919Sxy150489 
11794919Sxy150489 	return (E1000_SUCCESS);
11804919Sxy150489 }
11814919Sxy150489 
11824919Sxy150489 /*
11834919Sxy150489  * e1000_write_8bit_ctrl_reg - Writes 8bit Control register
11844919Sxy150489  * @hw: pointer to the HW structure
11854919Sxy150489  * @reg: 32bit register offset
11864919Sxy150489  * @offset: the register to write
11874919Sxy150489  * @data: the value to write.
11884919Sxy150489  *
11894919Sxy150489  * Writes the PHY register at offset with the value in data.
11904919Sxy150489  * This is a function pointer entry point called by drivers.
11914919Sxy150489  */
11924919Sxy150489 s32
11934919Sxy150489 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, u8 data)
11944919Sxy150489 {
11954919Sxy150489 	return (e1000_write_8bit_ctrl_reg_generic(hw, reg, offset, data));
11964919Sxy150489 }
1197