diff options
author | Bruce Allan <bruce.w.allan@intel.com> | 2008-08-26 21:37:06 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-09-03 10:08:13 -0400 |
commit | 4662e82b2cb41c60826e50474dd86dd5c6372b0c (patch) | |
tree | 75a99d62d28ad8ff5d9557f4665bae177218bb2a /drivers/net/e1000e/82571.c | |
parent | f4187b56e1f8a05dd110875d5094b21b51ebd79b (diff) |
e1000e: add support for new 82574L part
This new part has the same feature set as previous parts with the addition
of MSI-X support.
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/e1000e/82571.c')
-rw-r--r-- | drivers/net/e1000e/82571.c | 153 |
1 files changed, 140 insertions, 13 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 462351ca2c81..b2c910c52df9 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -38,6 +38,7 @@ | |||
38 | * 82573V Gigabit Ethernet Controller (Copper) | 38 | * 82573V Gigabit Ethernet Controller (Copper) |
39 | * 82573E Gigabit Ethernet Controller (Copper) | 39 | * 82573E Gigabit Ethernet Controller (Copper) |
40 | * 82573L Gigabit Ethernet Controller | 40 | * 82573L Gigabit Ethernet Controller |
41 | * 82574L Gigabit Network Connection | ||
41 | */ | 42 | */ |
42 | 43 | ||
43 | #include <linux/netdevice.h> | 44 | #include <linux/netdevice.h> |
@@ -54,6 +55,8 @@ | |||
54 | 55 | ||
55 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 | 56 | #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 |
56 | 57 | ||
58 | #define E1000_NVM_INIT_CTRL2_MNGM 0x6000 /* Manageability Operation Mode mask */ | ||
59 | |||
57 | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); | 60 | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); |
58 | static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); | 61 | static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); |
59 | static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); | 62 | static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); |
@@ -63,6 +66,8 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); | |||
63 | static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); | 66 | static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); |
64 | static s32 e1000_setup_link_82571(struct e1000_hw *hw); | 67 | static s32 e1000_setup_link_82571(struct e1000_hw *hw); |
65 | static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); | 68 | static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); |
69 | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); | ||
70 | static s32 e1000_led_on_82574(struct e1000_hw *hw); | ||
66 | 71 | ||
67 | /** | 72 | /** |
68 | * e1000_init_phy_params_82571 - Init PHY func ptrs. | 73 | * e1000_init_phy_params_82571 - Init PHY func ptrs. |
@@ -92,6 +97,9 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) | |||
92 | case e1000_82573: | 97 | case e1000_82573: |
93 | phy->type = e1000_phy_m88; | 98 | phy->type = e1000_phy_m88; |
94 | break; | 99 | break; |
100 | case e1000_82574: | ||
101 | phy->type = e1000_phy_bm; | ||
102 | break; | ||
95 | default: | 103 | default: |
96 | return -E1000_ERR_PHY; | 104 | return -E1000_ERR_PHY; |
97 | break; | 105 | break; |
@@ -111,6 +119,10 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) | |||
111 | if (phy->id != M88E1111_I_PHY_ID) | 119 | if (phy->id != M88E1111_I_PHY_ID) |
112 | return -E1000_ERR_PHY; | 120 | return -E1000_ERR_PHY; |
113 | break; | 121 | break; |
122 | case e1000_82574: | ||
123 | if (phy->id != BME1000_E_PHY_ID_R2) | ||
124 | return -E1000_ERR_PHY; | ||
125 | break; | ||
114 | default: | 126 | default: |
115 | return -E1000_ERR_PHY; | 127 | return -E1000_ERR_PHY; |
116 | break; | 128 | break; |
@@ -150,6 +162,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) | |||
150 | 162 | ||
151 | switch (hw->mac.type) { | 163 | switch (hw->mac.type) { |
152 | case e1000_82573: | 164 | case e1000_82573: |
165 | case e1000_82574: | ||
153 | if (((eecd >> 15) & 0x3) == 0x3) { | 166 | if (((eecd >> 15) & 0x3) == 0x3) { |
154 | nvm->type = e1000_nvm_flash_hw; | 167 | nvm->type = e1000_nvm_flash_hw; |
155 | nvm->word_size = 2048; | 168 | nvm->word_size = 2048; |
@@ -245,6 +258,17 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) | |||
245 | break; | 258 | break; |
246 | } | 259 | } |
247 | 260 | ||
261 | switch (hw->mac.type) { | ||
262 | case e1000_82574: | ||
263 | func->check_mng_mode = e1000_check_mng_mode_82574; | ||
264 | func->led_on = e1000_led_on_82574; | ||
265 | break; | ||
266 | default: | ||
267 | func->check_mng_mode = e1000e_check_mng_mode_generic; | ||
268 | func->led_on = e1000e_led_on_generic; | ||
269 | break; | ||
270 | } | ||
271 | |||
248 | return 0; | 272 | return 0; |
249 | } | 273 | } |
250 | 274 | ||
@@ -330,6 +354,8 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter) | |||
330 | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) | 354 | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) |
331 | { | 355 | { |
332 | struct e1000_phy_info *phy = &hw->phy; | 356 | struct e1000_phy_info *phy = &hw->phy; |
357 | s32 ret_val; | ||
358 | u16 phy_id = 0; | ||
333 | 359 | ||
334 | switch (hw->mac.type) { | 360 | switch (hw->mac.type) { |
335 | case e1000_82571: | 361 | case e1000_82571: |
@@ -345,6 +371,20 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) | |||
345 | case e1000_82573: | 371 | case e1000_82573: |
346 | return e1000e_get_phy_id(hw); | 372 | return e1000e_get_phy_id(hw); |
347 | break; | 373 | break; |
374 | case e1000_82574: | ||
375 | ret_val = e1e_rphy(hw, PHY_ID1, &phy_id); | ||
376 | if (ret_val) | ||
377 | return ret_val; | ||
378 | |||
379 | phy->id = (u32)(phy_id << 16); | ||
380 | udelay(20); | ||
381 | ret_val = e1e_rphy(hw, PHY_ID2, &phy_id); | ||
382 | if (ret_val) | ||
383 | return ret_val; | ||
384 | |||
385 | phy->id |= (u32)(phy_id); | ||
386 | phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); | ||
387 | break; | ||
348 | default: | 388 | default: |
349 | return -E1000_ERR_PHY; | 389 | return -E1000_ERR_PHY; |
350 | break; | 390 | break; |
@@ -421,7 +461,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) | |||
421 | if (ret_val) | 461 | if (ret_val) |
422 | return ret_val; | 462 | return ret_val; |
423 | 463 | ||
424 | if (hw->mac.type != e1000_82573) | 464 | if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574) |
425 | ret_val = e1000e_acquire_nvm(hw); | 465 | ret_val = e1000e_acquire_nvm(hw); |
426 | 466 | ||
427 | if (ret_val) | 467 | if (ret_val) |
@@ -461,6 +501,7 @@ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, | |||
461 | 501 | ||
462 | switch (hw->mac.type) { | 502 | switch (hw->mac.type) { |
463 | case e1000_82573: | 503 | case e1000_82573: |
504 | case e1000_82574: | ||
464 | ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); | 505 | ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); |
465 | break; | 506 | break; |
466 | case e1000_82571: | 507 | case e1000_82571: |
@@ -735,7 +776,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
735 | * Must acquire the MDIO ownership before MAC reset. | 776 | * Must acquire the MDIO ownership before MAC reset. |
736 | * Ownership defaults to firmware after a reset. | 777 | * Ownership defaults to firmware after a reset. |
737 | */ | 778 | */ |
738 | if (hw->mac.type == e1000_82573) { | 779 | if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { |
739 | extcnf_ctrl = er32(EXTCNF_CTRL); | 780 | extcnf_ctrl = er32(EXTCNF_CTRL); |
740 | extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; | 781 | extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; |
741 | 782 | ||
@@ -776,7 +817,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
776 | * Need to wait for Phy configuration completion before accessing | 817 | * Need to wait for Phy configuration completion before accessing |
777 | * NVM and Phy. | 818 | * NVM and Phy. |
778 | */ | 819 | */ |
779 | if (hw->mac.type == e1000_82573) | 820 | if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) |
780 | msleep(25); | 821 | msleep(25); |
781 | 822 | ||
782 | /* Clear any pending interrupt events. */ | 823 | /* Clear any pending interrupt events. */ |
@@ -843,7 +884,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw) | |||
843 | ew32(TXDCTL(0), reg_data); | 884 | ew32(TXDCTL(0), reg_data); |
844 | 885 | ||
845 | /* ...for both queues. */ | 886 | /* ...for both queues. */ |
846 | if (mac->type != e1000_82573) { | 887 | if (mac->type != e1000_82573 && mac->type != e1000_82574) { |
847 | reg_data = er32(TXDCTL(1)); | 888 | reg_data = er32(TXDCTL(1)); |
848 | reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | | 889 | reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | |
849 | E1000_TXDCTL_FULL_TX_DESC_WB | | 890 | E1000_TXDCTL_FULL_TX_DESC_WB | |
@@ -918,19 +959,28 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) | |||
918 | } | 959 | } |
919 | 960 | ||
920 | /* Device Control */ | 961 | /* Device Control */ |
921 | if (hw->mac.type == e1000_82573) { | 962 | if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { |
922 | reg = er32(CTRL); | 963 | reg = er32(CTRL); |
923 | reg &= ~(1 << 29); | 964 | reg &= ~(1 << 29); |
924 | ew32(CTRL, reg); | 965 | ew32(CTRL, reg); |
925 | } | 966 | } |
926 | 967 | ||
927 | /* Extended Device Control */ | 968 | /* Extended Device Control */ |
928 | if (hw->mac.type == e1000_82573) { | 969 | if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { |
929 | reg = er32(CTRL_EXT); | 970 | reg = er32(CTRL_EXT); |
930 | reg &= ~(1 << 23); | 971 | reg &= ~(1 << 23); |
931 | reg |= (1 << 22); | 972 | reg |= (1 << 22); |
932 | ew32(CTRL_EXT, reg); | 973 | ew32(CTRL_EXT, reg); |
933 | } | 974 | } |
975 | |||
976 | /* PCI-Ex Control Register */ | ||
977 | if (hw->mac.type == e1000_82574) { | ||
978 | reg = er32(GCR); | ||
979 | reg |= (1 << 22); | ||
980 | ew32(GCR, reg); | ||
981 | } | ||
982 | |||
983 | return; | ||
934 | } | 984 | } |
935 | 985 | ||
936 | /** | 986 | /** |
@@ -947,7 +997,7 @@ void e1000e_clear_vfta(struct e1000_hw *hw) | |||
947 | u32 vfta_offset = 0; | 997 | u32 vfta_offset = 0; |
948 | u32 vfta_bit_in_reg = 0; | 998 | u32 vfta_bit_in_reg = 0; |
949 | 999 | ||
950 | if (hw->mac.type == e1000_82573) { | 1000 | if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { |
951 | if (hw->mng_cookie.vlan_id != 0) { | 1001 | if (hw->mng_cookie.vlan_id != 0) { |
952 | /* | 1002 | /* |
953 | * The VFTA is a 4096b bit-field, each identifying | 1003 | * The VFTA is a 4096b bit-field, each identifying |
@@ -976,6 +1026,48 @@ void e1000e_clear_vfta(struct e1000_hw *hw) | |||
976 | } | 1026 | } |
977 | 1027 | ||
978 | /** | 1028 | /** |
1029 | * e1000_check_mng_mode_82574 - Check manageability is enabled | ||
1030 | * @hw: pointer to the HW structure | ||
1031 | * | ||
1032 | * Reads the NVM Initialization Control Word 2 and returns true | ||
1033 | * (>0) if any manageability is enabled, else false (0). | ||
1034 | **/ | ||
1035 | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw) | ||
1036 | { | ||
1037 | u16 data; | ||
1038 | |||
1039 | e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); | ||
1040 | return (data & E1000_NVM_INIT_CTRL2_MNGM) != 0; | ||
1041 | } | ||
1042 | |||
1043 | /** | ||
1044 | * e1000_led_on_82574 - Turn LED on | ||
1045 | * @hw: pointer to the HW structure | ||
1046 | * | ||
1047 | * Turn LED on. | ||
1048 | **/ | ||
1049 | static s32 e1000_led_on_82574(struct e1000_hw *hw) | ||
1050 | { | ||
1051 | u32 ctrl; | ||
1052 | u32 i; | ||
1053 | |||
1054 | ctrl = hw->mac.ledctl_mode2; | ||
1055 | if (!(E1000_STATUS_LU & er32(STATUS))) { | ||
1056 | /* | ||
1057 | * If no link, then turn LED on by setting the invert bit | ||
1058 | * for each LED that's "on" (0x0E) in ledctl_mode2. | ||
1059 | */ | ||
1060 | for (i = 0; i < 4; i++) | ||
1061 | if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == | ||
1062 | E1000_LEDCTL_MODE_LED_ON) | ||
1063 | ctrl |= (E1000_LEDCTL_LED0_IVRT << (i * 8)); | ||
1064 | } | ||
1065 | ew32(LEDCTL, ctrl); | ||
1066 | |||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | /** | ||
979 | * e1000_update_mc_addr_list_82571 - Update Multicast addresses | 1071 | * e1000_update_mc_addr_list_82571 - Update Multicast addresses |
980 | * @hw: pointer to the HW structure | 1072 | * @hw: pointer to the HW structure |
981 | * @mc_addr_list: array of multicast addresses to program | 1073 | * @mc_addr_list: array of multicast addresses to program |
@@ -1018,7 +1110,8 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw) | |||
1018 | * the default flow control setting, so we explicitly | 1110 | * the default flow control setting, so we explicitly |
1019 | * set it to full. | 1111 | * set it to full. |
1020 | */ | 1112 | */ |
1021 | if (hw->mac.type == e1000_82573) | 1113 | if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && |
1114 | hw->fc.type == e1000_fc_default) | ||
1022 | hw->fc.type = e1000_fc_full; | 1115 | hw->fc.type = e1000_fc_full; |
1023 | 1116 | ||
1024 | return e1000e_setup_link(hw); | 1117 | return e1000e_setup_link(hw); |
@@ -1045,6 +1138,7 @@ static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) | |||
1045 | 1138 | ||
1046 | switch (hw->phy.type) { | 1139 | switch (hw->phy.type) { |
1047 | case e1000_phy_m88: | 1140 | case e1000_phy_m88: |
1141 | case e1000_phy_bm: | ||
1048 | ret_val = e1000e_copper_link_setup_m88(hw); | 1142 | ret_val = e1000e_copper_link_setup_m88(hw); |
1049 | break; | 1143 | break; |
1050 | case e1000_phy_igp_2: | 1144 | case e1000_phy_igp_2: |
@@ -1114,11 +1208,10 @@ static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) | |||
1114 | return ret_val; | 1208 | return ret_val; |
1115 | } | 1209 | } |
1116 | 1210 | ||
1117 | if (hw->mac.type == e1000_82573 && | 1211 | if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && |
1118 | *data == ID_LED_RESERVED_F746) | 1212 | *data == ID_LED_RESERVED_F746) |
1119 | *data = ID_LED_DEFAULT_82573; | 1213 | *data = ID_LED_DEFAULT_82573; |
1120 | else if (*data == ID_LED_RESERVED_0000 || | 1214 | else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) |
1121 | *data == ID_LED_RESERVED_FFFF) | ||
1122 | *data = ID_LED_DEFAULT; | 1215 | *data = ID_LED_DEFAULT; |
1123 | 1216 | ||
1124 | return 0; | 1217 | return 0; |
@@ -1265,13 +1358,13 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) | |||
1265 | } | 1358 | } |
1266 | 1359 | ||
1267 | static struct e1000_mac_operations e82571_mac_ops = { | 1360 | static struct e1000_mac_operations e82571_mac_ops = { |
1268 | .mng_mode_enab = E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT, | 1361 | /* .check_mng_mode: mac type dependent */ |
1269 | /* .check_for_link: media type dependent */ | 1362 | /* .check_for_link: media type dependent */ |
1270 | .cleanup_led = e1000e_cleanup_led_generic, | 1363 | .cleanup_led = e1000e_cleanup_led_generic, |
1271 | .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, | 1364 | .clear_hw_cntrs = e1000_clear_hw_cntrs_82571, |
1272 | .get_bus_info = e1000e_get_bus_info_pcie, | 1365 | .get_bus_info = e1000e_get_bus_info_pcie, |
1273 | /* .get_link_up_info: media type dependent */ | 1366 | /* .get_link_up_info: media type dependent */ |
1274 | .led_on = e1000e_led_on_generic, | 1367 | /* .led_on: mac type dependent */ |
1275 | .led_off = e1000e_led_off_generic, | 1368 | .led_off = e1000e_led_off_generic, |
1276 | .update_mc_addr_list = e1000_update_mc_addr_list_82571, | 1369 | .update_mc_addr_list = e1000_update_mc_addr_list_82571, |
1277 | .reset_hw = e1000_reset_hw_82571, | 1370 | .reset_hw = e1000_reset_hw_82571, |
@@ -1312,6 +1405,22 @@ static struct e1000_phy_operations e82_phy_ops_m88 = { | |||
1312 | .write_phy_reg = e1000e_write_phy_reg_m88, | 1405 | .write_phy_reg = e1000e_write_phy_reg_m88, |
1313 | }; | 1406 | }; |
1314 | 1407 | ||
1408 | static struct e1000_phy_operations e82_phy_ops_bm = { | ||
1409 | .acquire_phy = e1000_get_hw_semaphore_82571, | ||
1410 | .check_reset_block = e1000e_check_reset_block_generic, | ||
1411 | .commit_phy = e1000e_phy_sw_reset, | ||
1412 | .force_speed_duplex = e1000e_phy_force_speed_duplex_m88, | ||
1413 | .get_cfg_done = e1000e_get_cfg_done, | ||
1414 | .get_cable_length = e1000e_get_cable_length_m88, | ||
1415 | .get_phy_info = e1000e_get_phy_info_m88, | ||
1416 | .read_phy_reg = e1000e_read_phy_reg_bm2, | ||
1417 | .release_phy = e1000_put_hw_semaphore_82571, | ||
1418 | .reset_phy = e1000e_phy_hw_reset_generic, | ||
1419 | .set_d0_lplu_state = e1000_set_d0_lplu_state_82571, | ||
1420 | .set_d3_lplu_state = e1000e_set_d3_lplu_state, | ||
1421 | .write_phy_reg = e1000e_write_phy_reg_bm2, | ||
1422 | }; | ||
1423 | |||
1315 | static struct e1000_nvm_operations e82571_nvm_ops = { | 1424 | static struct e1000_nvm_operations e82571_nvm_ops = { |
1316 | .acquire_nvm = e1000_acquire_nvm_82571, | 1425 | .acquire_nvm = e1000_acquire_nvm_82571, |
1317 | .read_nvm = e1000e_read_nvm_eerd, | 1426 | .read_nvm = e1000e_read_nvm_eerd, |
@@ -1375,3 +1484,21 @@ struct e1000_info e1000_82573_info = { | |||
1375 | .nvm_ops = &e82571_nvm_ops, | 1484 | .nvm_ops = &e82571_nvm_ops, |
1376 | }; | 1485 | }; |
1377 | 1486 | ||
1487 | struct e1000_info e1000_82574_info = { | ||
1488 | .mac = e1000_82574, | ||
1489 | .flags = FLAG_HAS_HW_VLAN_FILTER | ||
1490 | | FLAG_HAS_MSIX | ||
1491 | | FLAG_HAS_JUMBO_FRAMES | ||
1492 | | FLAG_HAS_WOL | ||
1493 | | FLAG_APME_IN_CTRL3 | ||
1494 | | FLAG_RX_CSUM_ENABLED | ||
1495 | | FLAG_HAS_SMART_POWER_DOWN | ||
1496 | | FLAG_HAS_AMT | ||
1497 | | FLAG_HAS_CTRLEXT_ON_LOAD, | ||
1498 | .pba = 20, | ||
1499 | .get_variants = e1000_get_variants_82571, | ||
1500 | .mac_ops = &e82571_mac_ops, | ||
1501 | .phy_ops = &e82_phy_ops_bm, | ||
1502 | .nvm_ops = &e82571_nvm_ops, | ||
1503 | }; | ||
1504 | |||