subport.h (23289B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2020 Broadcom Inc. All rights reserved. 7 * 8 */ 9 10 #ifndef __BCM_SUBPORT_H__ 11 #define __BCM_SUBPORT_H__ 12 13 #include <bcm/types.h> 14 15 #ifndef BCM_HIDE_DISPATCHABLE 16 17 /* Initialize/Cleanup the subport subsystem. */ 18 extern int bcm_subport_init( 19 int unit); 20 21 /* Initialize/Cleanup the subport subsystem. */ 22 extern int bcm_subport_cleanup( 23 int unit); 24 25 #endif /* BCM_HIDE_DISPATCHABLE */ 26 27 /* Subport group create flags. */ 28 #define BCM_SUBPORT_GROUP_WITH_ID 0x00000001 /* Add using the 29 specified ID. */ 30 #define BCM_SUBPORT_GROUP_TYPE_LINKPHY 0x00000002 /* Add a LinkPHY subport 31 group. */ 32 #define BCM_SUBPORT_GROUP_TYPE_SUBPORT_TAG 0x00000004 /* Add a 'subport tag' 33 (triple vlan tag) 34 subport group. */ 35 #define BCM_SUBPORT_GROUP_TYPE_SUBPORT_PKTTAG 0x00000008 /* Add a 'LLTAG tag' 36 (triple vlan tag) 37 subport group. */ 38 #define BCM_SUBPORT_GROUP_QUEUE 0x00000010 /* If set, use subport 39 group queues; Else, 40 use egress port 41 DiffServ queues. */ 42 #define BCM_SUBPORT_GROUP_TYPE_GENERAL 0x00000020 /* Add a general purpose 43 subport group. */ 44 45 /* Subport port property flags. */ 46 #define BCM_SUBPORT_PROPERTY_PHB 0x00000001 /* Subport port PHB is valid. 47 Packet's 'internal priority' 48 and 'color' will be derived 49 from subport port lookup. */ 50 51 #define BCM_SUBPORT_CONFIG_MAX_STREAMS 2 /* Max number of streams per 52 LinkPHY subport */ 53 54 /* bcm_subport_group_config_t */ 55 typedef struct bcm_subport_group_config_s { 56 uint32 flags; /* BCM_SUBPORT_GROUP_xxx. */ 57 bcm_gport_t port; /* Physical GPORT Identifier */ 58 bcm_vlan_t vlan; /* VLAN the group is attached to */ 59 int if_class; /* Interface class ID */ 60 uint32 prop_flags; /* Property flags for this subport group */ 61 bcm_gport_t queue_base; /* Subport group base queue */ 62 int qos_map_id; /* QoS map identifier which defines priorities 1-1 63 mapping to queue offsets (0 ~ 7). */ 64 } bcm_subport_group_config_t; 65 66 /* Initialize a subport group config structure. */ 67 extern void bcm_subport_group_config_t_init( 68 bcm_subport_group_config_t *config); 69 70 #ifndef BCM_HIDE_DISPATCHABLE 71 72 /* Create a subport group. */ 73 extern int bcm_subport_group_create( 74 int unit, 75 bcm_subport_group_config_t *config, 76 bcm_gport_t *group); 77 78 /* 79 * Destroy a subport group and all the subports that are part of the 80 * group. 81 */ 82 extern int bcm_subport_group_destroy( 83 int unit, 84 bcm_gport_t group); 85 86 /* Get a subport group. */ 87 extern int bcm_subport_group_get( 88 int unit, 89 bcm_gport_t group, 90 bcm_subport_group_config_t *config); 91 92 #endif /* BCM_HIDE_DISPATCHABLE */ 93 94 /* bcm_subport_match_t */ 95 typedef enum bcm_subport_match_e { 96 BCM_SUBPORT_MATCH_INVALID = 0, /* Illegal. */ 97 BCM_SUBPORT_MATCH_PKT_VID = 1, /* Mod/port/trunk + LLTAG VID. */ 98 BCM_SUBPORT_MATCH_PKT_VID_INNER_VLAN = 2, /* Mod/port/trunk + LLTAG VID + inner 99 VLAN. */ 100 BCM_SUBPORT_MATCH_PKT_VID_OUTER_VLAN = 3, /* Mod/port/trunk + LLTAG VID + outer 101 VLAN. */ 102 BCM_SUBPORT_MATCH_COUNT = 4 /* Must be last. */ 103 } bcm_subport_match_t; 104 105 /* bcm_subport_config_t */ 106 typedef struct bcm_subport_config_s { 107 bcm_gport_t group; /* Subport group */ 108 bcm_vlan_t pkt_vlan; /* Packet 16-bit VLAN tag */ 109 bcm_vlan_t inner_vlan; /* 12-bit inner VLAN */ 110 bcm_vlan_t outer_vlan; /* 12-bit outerVLAN */ 111 int int_pri; /* Internal Priority for this subport 112 port */ 113 uint32 prop_flags; /* Property flags for this subport port */ 114 uint16 stream_id_array[BCM_SUBPORT_CONFIG_MAX_STREAMS]; /* LinkPHY fragment header Stream ID 115 array to be associated with the 116 LinkPHY subport port. */ 117 int num_streams; /* Number of streams associated with the 118 LinkPHY subport port. */ 119 bcm_color_t color; /* (internal) color or drop precedence 120 for this subport port. */ 121 bcm_subport_match_t criteria; /* match criteria. */ 122 bcm_gport_t subport_modport; /* CoE - System port associated with the 123 subport tag */ 124 } bcm_subport_config_t; 125 126 /* Initialize a subport config structure. */ 127 extern void bcm_subport_config_t_init( 128 bcm_subport_config_t *config); 129 130 #ifndef BCM_HIDE_DISPATCHABLE 131 132 /* Add a subport to a subport group. */ 133 extern int bcm_subport_port_add( 134 int unit, 135 bcm_subport_config_t *config, 136 bcm_gport_t *port); 137 138 /* Delete a subport. */ 139 extern int bcm_subport_port_delete( 140 int unit, 141 bcm_gport_t port); 142 143 /* Get the subport configuration for the given gport identifier. */ 144 extern int bcm_subport_port_get( 145 int unit, 146 bcm_gport_t port, 147 bcm_subport_config_t *config); 148 149 #endif /* BCM_HIDE_DISPATCHABLE */ 150 151 /* bcm_subport_port_traverse_cb */ 152 typedef int (*bcm_subport_port_traverse_cb)( 153 int unit, 154 bcm_gport_t port, 155 bcm_subport_config_t *config, 156 void *user_data); 157 158 #ifndef BCM_HIDE_DISPATCHABLE 159 160 /* 161 * Traverse the existing subports and call the user-supplied callback 162 * function for each one. 163 */ 164 extern int bcm_subport_port_traverse( 165 int unit, 166 bcm_subport_port_traverse_cb cb, 167 void *user_data); 168 169 /* 170 * Traverse the existing subports under a given subport group and call 171 * the 172 * user-supplied callback function for each one. 173 */ 174 extern int bcm_subport_group_traverse( 175 int unit, 176 bcm_gport_t subport_group, 177 bcm_subport_port_traverse_cb cb, 178 void *user_data); 179 180 #endif /* BCM_HIDE_DISPATCHABLE */ 181 182 /* LinkPHY configuration action mask */ 183 #define BCM_SUBPORT_LINKPHY_BASE_STREAM_ID 0x00000001 184 #define BCM_SUBPORT_LINKPHY_HEADER_MODE 0x00000002 185 #define BCM_SUBPORT_LINKPHY_RX_CHECK_FLAGS 0x00000004 186 #define BCM_SUBPORT_LINKPHY_RX_VLAN_TPID 0x00000008 187 #define BCM_SUBPORT_LINKPHY_RX_NEAREND_MAC 0x00000010 188 #define BCM_SUBPORT_LINKPHY_RX_FAREND_MAC 0x00000020 189 #define BCM_SUBPORT_LINKPHY_RX_DFC_DEST_MAC 0x00000040 190 #define BCM_SUBPORT_LINKPHY_RX_DFC_OPCODE 0x00000080 191 #define BCM_SUBPORT_LINKPHY_RX_DFC_TIME 0x00000100 192 #define BCM_SUBPORT_LINKPHY_RX_DFC_MAC_TYPE 0x00000200 193 #define BCM_SUBPORT_LINKPHY_TX_VLAN_TPID 0x00000400 194 #define BCM_SUBPORT_LINKPHY_TX_NEAREND_MAC 0x00000800 195 #define BCM_SUBPORT_LINKPHY_TX_FAREND_MAC 0x00001000 196 #define BCM_SUBPORT_LINKPHY_TX_PENULTIMATE_MODE 0x00002000 /* If this flag is 197 selected then TX 198 penultimate mode is 199 enabled. The 200 penultimate-fragment 201 of the frame would be 202 64-bytes(Payload-size) 203 to avoid padding in 204 the last-fragment. If 205 this flag is 206 deselected then TX 207 penultimate mode is 208 disabled. */ 209 #define BCM_SUBPORT_LINKPHY_ALL 0xFFFFFFFF 210 211 /* Check flags for received LinkPHY fragments */ 212 #define BCM_SUBPORT_LINKPHY_RX_NEAREND_MAC_CHECK 0x00000001 /* enable/disable nearend 213 MAC compare */ 214 #define BCM_SUBPORT_LINKPHY_RX_FAREND_MAC_CHECK 0x00000002 /* enable/disable far end 215 MAC compare */ 216 #define BCM_SUBPORT_LINKPHY_RX_DFC_DEST_MAC_CHECK 0x00000004 /* enable/disable DFC 217 destination MAC 218 compare */ 219 #define BCM_SUBPORT_LINKPHY_RX_DFC_OPCODE_CHECK 0x00000008 /* enable/disable DFC 220 opcode compare */ 221 #define BCM_SUBPORT_LINKPHY_RX_DFC_TIME_CHECK 0x00000010 /* enable/disable DFC 222 time compare */ 223 224 /* LinkPHY fragment header mode */ 225 typedef enum bcm_subport_group_linkphy_header_mode_e { 226 bcmSubportLinkphyHeaderModeEthAdapt = 0, /* Ethernet-Adaptation LinkPHY header 227 mode */ 228 bcmSubportLinkphyHeaderModeTciLength = 1 /* TCI+Length LinkPHY header mode */ 229 } bcm_subport_group_linkphy_header_mode_t; 230 231 /* Subport statistics */ 232 typedef enum bcm_subport_stat_e { 233 bcmSubportLinkPhyStatRxFragmentBytes = 0, /* LinkPHY subport Rx fragment bytes 234 statistics */ 235 bcmSubportLinkPhyStatRxFragments = 1, /* LinkPHY subport Rx fragments 236 statistics */ 237 bcmSubportLinkPhyStatRxFrameBytes = 2, /* LinkPHY subport Rx frame bytes 238 statistics */ 239 bcmSubportLinkPhyStatRxFrames = 3, /* LinkPHY subport Rx frames statistics */ 240 bcmSubportLinkPhyStatTxFragmentBytes = 4, /* LinkPHY subport Tx fragment bytes 241 statistics */ 242 bcmSubportLinkPhyStatTxFragments = 5, /* LinkPHY subport Tx fragments 243 statistics */ 244 bcmSubportLinkPhyStatTxFrameBytes = 6, /* LinkPHY subport Tx frame bytes 245 statistics */ 246 bcmSubportLinkPhyStatTxFrames = 7 /* LinkPHY subport Tx frames statistics */ 247 } bcm_subport_stat_t; 248 249 /* List of Linkphy RX errors */ 250 typedef enum bcm_subport_linkphy_rx_error_e { 251 bcmSubportLinkphyRxErrorMaxFrameSize = 0, /* Linkphy RX error due to Frame with 252 max frame size */ 253 bcmSubportLinkphyRxErrorRuntFrame = 1, /* Linkphy RX error due to Runt frame */ 254 bcmSubportLinkphyRxErrorDfcLength = 2, /* Linkphy RX error due to a DFC Frame 255 with unacceptable length */ 256 bcmSubportLinkphyRxErrorDfcDropPortPurge = 3, /* Linkphy RX error due to a DFC Frame 257 drop due to port purge */ 258 bcmSubportLinkphyRxErrorDfcTime = 4, /* Linkphy RX error due to a DFC Frame 259 with Time error */ 260 bcmSubportLinkphyRxErrorDfcOpcode = 5, /* Linkphy RX error due to a DFC Frame 261 with Opcode error */ 262 bcmSubportLinkphyRxErrorLengthZero = 6, /* Linkphy RX error due to Fragment with 263 header length zero */ 264 bcmSubportLinkphyRxErrorNonEofPaddedFragment = 7, /* Linkphy RX error due to Frame with 265 non-EOF padded fragment */ 266 bcmSubportLinkphyRxErrorHdrLengthGtFragmentLength = 8, /* Linkphy RX error due to Fragment with 267 header length greater than actual 268 fragment length */ 269 bcmSubportLinkphyRxErrorFraming = 9, /* Linkphy RX error due to Frame with 270 SOF/EOF/MOF errors */ 271 bcmSubportLinkphyRxErrorFrameCrc = 10, /* Linkphy RX error due to Frame with 272 CRC error. NA for DFC frame */ 273 bcmSubportLinkphyRxErrorStreamIdUnexpected = 11, /* Linkphy RX error due to Fragment with 274 unexpected streamId */ 275 bcmSubportLinkphyRxErrorMacSA = 12, /* Linkphy RX error due to Data fragment 276 or DFC frame that does not match 277 configured MAC SA */ 278 bcmSubportLinkphyRxErrorMacDA = 13, /* Linkphy RX error due to Data fragment 279 or DFC frame that does not match 280 configured MAC DA */ 281 bcmSubportLinkphyRxErrorEthertype = 14, /* Linkphy RX error due to Data fragment 282 or DFC frame that does not match 283 configured data TPID or DFC EtherType 284 respectively */ 285 bcmSubportLinkphyRxErrorCount = 15 /* Not an usable value. Always last */ 286 } bcm_subport_linkphy_rx_error_t; 287 288 /* Bitmap of Linkphy RX errors */ 289 typedef struct bcm_subport_linkphy_rx_errors_s { 290 SHR_BITDCL w[_SHR_BITDCLSIZE(bcmSubportLinkphyRxErrorCount)]; 291 } bcm_subport_linkphy_rx_errors_t; 292 293 /* Macros to manipulate the bitmap of Linkphy RX errors */ 294 #define BCM_SUBPORT_LINKPHY_RX_ERROR_SET(_error_types, _error_type) SHR_BITSET(((_error_types).w), (_error_type)) 295 #define BCM_SUBPORT_LINKPHY_RX_ERROR_GET(_error_types, _error_type) SHR_BITGET(((_error_types).w), (_error_type)) 296 #define BCM_SUBPORT_LINKPHY_RX_ERROR_CLEAR(_error_types, _error_type) SHR_BITCLR(((_error_types).w), (_error_type)) 297 #define BCM_SUBPORT_LINKPHY_RX_ERROR_SET_ALL(_error_types) SHR_BITSET_RANGE(((_error_types).w), 0, bcmSubportLinkphyRxErrorCount) 298 #define BCM_SUBPORT_LINKPHY_RX_ERROR_CLEAR_ALL(_error_types) SHR_BITCLR_RANGE(((_error_types).w), 0, bcmSubportLinkphyRxErrorCount) 299 300 /* LinkPHY configuration parameters per port. */ 301 typedef struct bcm_subport_group_linkphy_config_s { 302 uint32 action_mask; /* BCM_SUBPORT_LINKPHY_xxx flags */ 303 uint16 base_stream_id; /* External Stream ID base */ 304 bcm_subport_group_linkphy_header_mode_t header_mode; /* LinkPHY fragment header mode */ 305 uint32 rx_check_flags; /* flags 306 BCM_SUBPORT_LINKPHY_RX_XXX_CHECK for 307 comparing RXed fragment header 308 parameters */ 309 uint16 rx_vlan_tpid; /* Expected Vlan TPID in header of 310 LinkPHY fragments RXed */ 311 bcm_mac_t rx_nearend_mac; /* Expected near end MAC address in 312 header of LinkPHY fragments RXed */ 313 bcm_mac_t rx_farend_mac; /* Expected far end MAC address in 314 header of LinkPHY fragments RXed */ 315 bcm_mac_t rx_dfc_dest_mac; /* Expected Destination MAC address in 316 header of DFC fragments RXed */ 317 uint16 rx_dfc_opcode; /* Expected opcode in header of DFC 318 fragments RXed */ 319 uint16 rx_dfc_time; /* Expected TIME in header of DFC 320 fragments RXed */ 321 uint16 rx_dfc_mac_type; /* Expected EtherType in header of DFC 322 fragments RXed */ 323 uint16 tx_vlan_tpid; /* Vlan TPID to be set in header of 324 LinkPHY fragments TXed */ 325 bcm_mac_t tx_nearend_mac; /* Near end MAC address to be set in 326 header of LinkPHY fragments TXed */ 327 bcm_mac_t tx_farend_mac; /* Far end MAC address to be set in 328 header of LinkPHY fragments TXed */ 329 } bcm_subport_group_linkphy_config_t; 330 331 /* The maximum size of Linkphy RX fragment */ 332 #define BCM_SUBPORT_LINKPHY_MAX_FRAGMENT_SIZE 192 333 334 /* Data related to the fragment with the error */ 335 typedef struct bcm_subport_linkphy_rx_error_data_s { 336 bcm_port_t port; /* Physical port on which the errored 337 fragment was received */ 338 uint16 ext_stream_id; /* The external stream id in the errored 339 fragment */ 340 uint8 fragment_data[BCM_SUBPORT_LINKPHY_MAX_FRAGMENT_SIZE]; /* The entire fragment data */ 341 } bcm_subport_linkphy_rx_error_data_t; 342 343 /* Initialize a LinkPHY port config structure. */ 344 extern void bcm_subport_group_linkphy_config_t_init( 345 bcm_subport_group_linkphy_config_t *linkphy_config); 346 347 #ifndef BCM_HIDE_DISPATCHABLE 348 349 /* Set LinkPHY configuration parameters for a given port. */ 350 extern int bcm_subport_group_linkphy_config_set( 351 int unit, 352 bcm_gport_t port, 353 bcm_subport_group_linkphy_config_t *linkphy_config); 354 355 /* Get LinkPHY configuration parameters for a given port. */ 356 extern int bcm_subport_group_linkphy_config_get( 357 int unit, 358 bcm_gport_t port, 359 bcm_subport_group_linkphy_config_t *linkphy_config); 360 361 /* Set the statistics value for a given subport and statistics type. */ 362 extern int bcm_subport_port_stat_set( 363 int unit, 364 bcm_gport_t port, 365 int stream_id, 366 bcm_subport_stat_t stat_type, 367 uint64 val); 368 369 /* Get the statistics value for a given subport and statistics type. */ 370 extern int bcm_subport_port_stat_get( 371 int unit, 372 bcm_gport_t port, 373 int stream_id, 374 bcm_subport_stat_t stat_type, 375 uint64 *val); 376 377 #endif /* BCM_HIDE_DISPATCHABLE */ 378 379 /* 380 * BCM_SUBPORT_LINKPHY_RX_ERROR_CB_XXX flags - Used in callback functions 381 * for Linkphy RX errors 382 */ 383 #define BCM_SUBPORT_LINKPHY_RX_ERROR_CB_DATA_VALID 0x1 /* Indicates that the 384 callback data is valid */ 385 386 /* Callback function for a given Linkphy RX error type */ 387 typedef int (*bcm_subport_linkphy_rx_error_callback)( 388 int unit, 389 bcm_subport_linkphy_rx_error_t error_type, 390 uint32 flags, 391 bcm_subport_linkphy_rx_error_data_t *error_data, 392 void *user_data); 393 394 /* Information structure passed to Linkphy RX error registration */ 395 typedef struct bcm_subport_linkphy_rx_error_reg_info_s { 396 bcm_subport_linkphy_rx_error_callback cb; /* Callback to be registered */ 397 int data_log_enable; /* To enable/disable data logging for 398 given set of errors */ 399 } bcm_subport_linkphy_rx_error_reg_info_t; 400 401 /* Initialize the bcm_subport_linkphy_rx_error_reg_info_t structure */ 402 extern void bcm_subport_linkphy_rx_error_reg_info_t_init( 403 bcm_subport_linkphy_rx_error_reg_info_t *reg_info); 404 405 #ifndef BCM_HIDE_DISPATCHABLE 406 407 /* Register a callback function for a Linkphy RX error. */ 408 extern int bcm_subport_linkphy_rx_error_register( 409 int unit, 410 bcm_subport_linkphy_rx_errors_t errors, 411 bcm_subport_linkphy_rx_error_reg_info_t *reg_info, 412 void *user_data); 413 414 /* De-Register a callback function for a Linkphy RX error. */ 415 extern int bcm_subport_linkphy_rx_error_unregister( 416 int unit, 417 bcm_subport_linkphy_rx_errors_t errors); 418 419 /* 420 * Given a subport gport, returns the corresponding module and port 421 * associated with that subport. 422 * This is only applicable on devices BCM5645x, BCM5626x, BCM5646x, 423 * BCM5686x, BCM5656x and 424 * BCM5676x that support CoE applications like Subtag and LinkPhy. 425 */ 426 extern int bcm_subport_gport_modport_get( 427 int unit, 428 bcm_gport_t subport_gport, 429 bcm_module_t *module, 430 bcm_port_t *port); 431 432 #endif /* BCM_HIDE_DISPATCHABLE */ 433 434 /* subport port group identifier. */ 435 typedef uint32 bcm_subport_port_group_t; 436 437 #define BCM_SUBPORT_PORT_GROUP_WITH_ID (1 << 0) /* Port group is created with 438 id. */ 439 440 #ifndef BCM_HIDE_DISPATCHABLE 441 442 /* Create port group id. */ 443 extern int bcm_subport_port_group_id_create( 444 int unit, 445 uint32 options, 446 bcm_subport_port_group_t *port_group_id); 447 448 /* Destroy port group id. */ 449 extern int bcm_subport_port_group_id_destroy( 450 int unit, 451 bcm_subport_port_group_t port_group_id); 452 453 /* Get port group id. */ 454 extern int bcm_subport_port_group_id_get( 455 int unit, 456 bcm_subport_port_group_t port_group_id); 457 458 /* 459 * Destroy all the ports groups which do not have subports attached to 460 * them. 461 */ 462 extern int bcm_subport_port_group_id_destroy_all( 463 int unit); 464 465 /* 466 * Get all the port group ids created in the system. User will have to 467 * call this API first with max_size = 0 to get the exact number of 468 * elements. array_size will return the actual number of ids present in 469 * the system. In the subsequent call, user can allocate memory and ask 470 * for less/equal number of ids than array_size. 471 */ 472 extern int bcm_subport_port_group_id_get_all( 473 int unit, 474 int max_size, 475 bcm_subport_port_group_t *port_group_id_array, 476 int *array_size); 477 478 /* Set multiple subports gports in port group. */ 479 extern int bcm_subport_port_group_subport_multi_set( 480 int unit, 481 bcm_subport_port_group_t port_group_id, 482 int num_subports, 483 bcm_gport_t *subport_gports); 484 485 /* 486 * Get all the subports added in this port group. User will have to call 487 * this API first with max_subports = 0 to get the exact number of 488 * elements. num_subports will return the actual number of subports 489 * present in this port group. In the subsequent call, user can allocate 490 * memory and ask for less/equal number of subports than num_subports. 491 */ 492 extern int bcm_subport_port_group_subport_multi_get( 493 int unit, 494 bcm_subport_port_group_t port_group_id, 495 int max_subports, 496 bcm_gport_t *subport_gports, 497 int *num_subports); 498 499 /* Create subport profile id for l3 tunnel allowed subports. */ 500 extern int bcm_subport_tunnel_pbmp_profile_create( 501 int unit, 502 int num_subports, 503 bcm_gport_t *subport_gport, 504 int *subport_pbmp_profile_id); 505 506 /* Destoy subport profile. */ 507 extern int bcm_subport_tunnel_pbmp_profile_destroy( 508 int unit, 509 int subport_pbmp_profile_id); 510 511 /* Get subport profile for l3 tunnel allowed subports. */ 512 extern int bcm_subport_tunnel_pbmp_profile_get( 513 int unit, 514 int num_subports, 515 bcm_gport_t *subport_gport, 516 int *subport_pbmp_profile_id); 517 518 /* 519 * Destroy all the subport pbmp profiles which are not linked to any l3 520 * tunnel. 521 */ 522 extern int bcm_subport_tunnel_pbmp_profile_destroy_all( 523 int unit); 524 525 #endif /* BCM_HIDE_DISPATCHABLE */ 526 527 #endif /* __BCM_SUBPORT_H__ */