mirror of https://github.com/ipxe/ipxe.git
[hermon] Use Ethernet MAC as eIPoIB local EMAC
The eIPoIB local Ethernet MAC is currently constructed from the port GUID. Given a base GUID/MAC value of N, Mellanox seems to populate: Node GUID: N + 0 Port 1 GUID: N + 1 Port 2 GUID: N + 2 and Port 1 MAC: N + 0 Port 2 MAC: N + 1 This causes a duplicate local MAC address when port 1 is configured as Infiniband and port 2 as Ethernet, since both will derive their MAC address as (N + 1). Fix by using the port's Ethernet MAC as the eIPoIB local EMAC. This is a behavioural change that could potentially break configurations that rely on the local EMAC value, such as a DHCP server relying on the chaddr field for DHCP reservations. Signed-off-by: Christian Iversen <ci@iversenit.dk> Modified-by: Michael Brown <mcb30@ipxe.org> Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/234/head
parent
6cb12ee2b0
commit
699b9f1d1b
|
@ -3179,6 +3179,9 @@ static int hermon_register_ibdev ( struct hermon *hermon,
|
|||
struct ib_device *ibdev = port->ibdev;
|
||||
int rc;
|
||||
|
||||
/* Use Ethernet MAC as eIPoIB local EMAC */
|
||||
memcpy ( ibdev->lemac, port->eth_mac.raw, ETH_ALEN );
|
||||
|
||||
/* Initialise parameters using SMC */
|
||||
ib_smc_init ( ibdev, hermon_mad );
|
||||
|
||||
|
@ -3495,24 +3498,10 @@ static int hermon_register_netdev ( struct hermon *hermon,
|
|||
struct hermon_port *port ) {
|
||||
struct net_device *netdev = port->netdev;
|
||||
struct ib_device *ibdev = port->ibdev;
|
||||
struct hermonprm_query_port_cap query_port;
|
||||
union {
|
||||
uint8_t bytes[8];
|
||||
uint32_t dwords[2];
|
||||
} mac;
|
||||
int rc;
|
||||
|
||||
/* Retrieve MAC address */
|
||||
if ( ( rc = hermon_cmd_query_port ( hermon, ibdev->port,
|
||||
&query_port ) ) != 0 ) {
|
||||
DBGC ( hermon, "Hermon %p port %d could not query port: %s\n",
|
||||
hermon, ibdev->port, strerror ( rc ) );
|
||||
goto err_query_port;
|
||||
}
|
||||
mac.dwords[0] = htonl ( MLX_GET ( &query_port, mac_47_32 ) );
|
||||
mac.dwords[1] = htonl ( MLX_GET ( &query_port, mac_31_0 ) );
|
||||
memcpy ( netdev->hw_addr,
|
||||
&mac.bytes[ sizeof ( mac.bytes ) - ETH_ALEN ], ETH_ALEN );
|
||||
/* Set MAC address */
|
||||
memcpy ( netdev->hw_addr, port->eth_mac.raw, ETH_ALEN );
|
||||
|
||||
/* Register network device */
|
||||
if ( ( rc = register_netdev ( netdev ) ) != 0 ) {
|
||||
|
@ -3536,7 +3525,6 @@ static int hermon_register_netdev ( struct hermon *hermon,
|
|||
err_register_nvo:
|
||||
unregister_netdev ( netdev );
|
||||
err_register_netdev:
|
||||
err_query_port:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -3674,6 +3662,10 @@ static int hermon_set_port_type ( struct hermon *hermon,
|
|||
( ( ib_supported && eth_supported ) ? " and" : "" ),
|
||||
( eth_supported ? " Ethernet" : "" ) );
|
||||
|
||||
/* Record Ethernet MAC address */
|
||||
port->eth_mac.part.h = htons ( MLX_GET ( &query_port, mac_47_32 ) );
|
||||
port->eth_mac.part.l = htonl ( MLX_GET ( &query_port, mac_31_0 ) );
|
||||
|
||||
/* Sense network, if applicable */
|
||||
if ( ib_supported && eth_supported ) {
|
||||
|
||||
|
|
|
@ -822,6 +822,15 @@ struct hermon_port_type {
|
|||
struct hermon_port *port );
|
||||
};
|
||||
|
||||
/** A Hermon port Ethernet MAC address */
|
||||
union hermon_port_mac {
|
||||
struct {
|
||||
uint16_t h;
|
||||
uint32_t l;
|
||||
} __attribute__ (( packed )) part;
|
||||
uint8_t raw[ETH_ALEN];
|
||||
};
|
||||
|
||||
/** A Hermon port */
|
||||
struct hermon_port {
|
||||
/** Infiniband device */
|
||||
|
@ -832,6 +841,8 @@ struct hermon_port {
|
|||
struct ib_completion_queue *eth_cq;
|
||||
/** Ethernet queue pair */
|
||||
struct ib_queue_pair *eth_qp;
|
||||
/** Ethernet MAC */
|
||||
union hermon_port_mac eth_mac;
|
||||
/** Port type */
|
||||
struct hermon_port_type *type;
|
||||
/** Non-volatile option storage */
|
||||
|
|
Loading…
Reference in New Issue