Skip to content

Commit 4dce97b

Browse files
committed
Merge branch 'ncsi-mac-address-command'
Patrick Williams says: ==================== net/ncsi: Add NC-SI 1.2 Get MC MAC Address command NC-SI 1.2 has now been published[1] and adds a new command for "Get MC MAC Address". This is often used by BMCs to get the assigned MAC address for the channel used by the BMC. This change set has been tested on a Broadcomm 200G NIC with updated firmware for NC-SI 1.2 and at least one other non-public NIC design. 1. https://www.dmtf.org/sites/default/files/standards/documents/DSP0222_1.2.0.pdf ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f967226 + b8291cf commit 4dce97b

File tree

6 files changed

+98
-29
lines changed

6 files changed

+98
-29
lines changed

net/ncsi/internal.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,11 @@ enum {
105105

106106

107107
struct ncsi_channel_version {
108-
u32 version; /* Supported BCD encoded NCSI version */
109-
u32 alpha2; /* Supported BCD encoded NCSI version */
108+
u8 major; /* NCSI version major */
109+
u8 minor; /* NCSI version minor */
110+
u8 update; /* NCSI version update */
111+
char alpha1; /* NCSI version alpha1 */
112+
char alpha2; /* NCSI version alpha2 */
110113
u8 fw_name[12]; /* Firmware name string */
111114
u32 fw_version; /* Firmware version */
112115
u16 pci_ids[4]; /* PCI identification */

net/ncsi/ncsi-cmd.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ static struct ncsi_cmd_handler {
270270
{ NCSI_PKT_CMD_GPS, 0, ncsi_cmd_handler_default },
271271
{ NCSI_PKT_CMD_OEM, -1, ncsi_cmd_handler_oem },
272272
{ NCSI_PKT_CMD_PLDM, 0, NULL },
273-
{ NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default }
273+
{ NCSI_PKT_CMD_GPUUID, 0, ncsi_cmd_handler_default },
274+
{ NCSI_PKT_CMD_GMCMA, 0, ncsi_cmd_handler_default }
274275
};
275276

276277
static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca)

net/ncsi/ncsi-manage.c

+10-19
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,6 @@ static int set_one_vid(struct ncsi_dev_priv *ndp, struct ncsi_channel *nc,
689689
return 0;
690690
}
691691

692-
#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)
693-
694692
static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca)
695693
{
696694
unsigned char data[NCSI_OEM_INTEL_CMD_KEEP_PHY_LEN];
@@ -716,10 +714,6 @@ static int ncsi_oem_keep_phy_intel(struct ncsi_cmd_arg *nca)
716714
return ret;
717715
}
718716

719-
#endif
720-
721-
#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
722-
723717
/* NCSI OEM Command APIs */
724718
static int ncsi_oem_gma_handler_bcm(struct ncsi_cmd_arg *nca)
725719
{
@@ -856,8 +850,6 @@ static int ncsi_gma_handler(struct ncsi_cmd_arg *nca, unsigned int mf_id)
856850
return nch->handler(nca);
857851
}
858852

859-
#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
860-
861853
/* Determine if a given channel from the channel_queue should be used for Tx */
862854
static bool ncsi_channel_is_tx(struct ncsi_dev_priv *ndp,
863855
struct ncsi_channel *nc)
@@ -1039,20 +1031,23 @@ static void ncsi_configure_channel(struct ncsi_dev_priv *ndp)
10391031
goto error;
10401032
}
10411033

1042-
nd->state = ncsi_dev_state_config_oem_gma;
1034+
nd->state = IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
1035+
? ncsi_dev_state_config_oem_gma
1036+
: ncsi_dev_state_config_clear_vids;
10431037
break;
10441038
case ncsi_dev_state_config_oem_gma:
10451039
nd->state = ncsi_dev_state_config_clear_vids;
1046-
ret = -1;
10471040

1048-
#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
1049-
nca.type = NCSI_PKT_CMD_OEM;
10501041
nca.package = np->id;
10511042
nca.channel = nc->id;
10521043
ndp->pending_req_num = 1;
1053-
ret = ncsi_gma_handler(&nca, nc->version.mf_id);
1054-
#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
1055-
1044+
if (nc->version.major >= 1 && nc->version.minor >= 2) {
1045+
nca.type = NCSI_PKT_CMD_GMCMA;
1046+
ret = ncsi_xmit_cmd(&nca);
1047+
} else {
1048+
nca.type = NCSI_PKT_CMD_OEM;
1049+
ret = ncsi_gma_handler(&nca, nc->version.mf_id);
1050+
}
10561051
if (ret < 0)
10571052
schedule_work(&ndp->work);
10581053

@@ -1404,7 +1399,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
14041399

14051400
schedule_work(&ndp->work);
14061401
break;
1407-
#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_GET_MAC)
14081402
case ncsi_dev_state_probe_mlx_gma:
14091403
ndp->pending_req_num = 1;
14101404

@@ -1429,7 +1423,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
14291423

14301424
nd->state = ncsi_dev_state_probe_cis;
14311425
break;
1432-
#endif /* CONFIG_NCSI_OEM_CMD_GET_MAC */
14331426
case ncsi_dev_state_probe_cis:
14341427
ndp->pending_req_num = NCSI_RESERVED_CHANNEL;
14351428

@@ -1447,7 +1440,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
14471440
if (IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY))
14481441
nd->state = ncsi_dev_state_probe_keep_phy;
14491442
break;
1450-
#if IS_ENABLED(CONFIG_NCSI_OEM_CMD_KEEP_PHY)
14511443
case ncsi_dev_state_probe_keep_phy:
14521444
ndp->pending_req_num = 1;
14531445

@@ -1460,7 +1452,6 @@ static void ncsi_probe_channel(struct ncsi_dev_priv *ndp)
14601452

14611453
nd->state = ncsi_dev_state_probe_gvi;
14621454
break;
1463-
#endif /* CONFIG_NCSI_OEM_CMD_KEEP_PHY */
14641455
case ncsi_dev_state_probe_gvi:
14651456
case ncsi_dev_state_probe_gc:
14661457
case ncsi_dev_state_probe_gls:

net/ncsi/ncsi-netlink.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ static int ncsi_write_channel_info(struct sk_buff *skb,
7171
if (nc == nc->package->preferred_channel)
7272
nla_put_flag(skb, NCSI_CHANNEL_ATTR_FORCED);
7373

74-
nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MAJOR, nc->version.version);
75-
nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MINOR, nc->version.alpha2);
74+
nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MAJOR, nc->version.major);
75+
nla_put_u32(skb, NCSI_CHANNEL_ATTR_VERSION_MINOR, nc->version.minor);
7676
nla_put_string(skb, NCSI_CHANNEL_ATTR_VERSION_STR, nc->version.fw_name);
7777

7878
vid_nest = nla_nest_start_noflag(skb, NCSI_CHANNEL_ATTR_VLAN_LIST);

net/ncsi/ncsi-pkt.h

+15-2
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,12 @@ struct ncsi_rsp_gls_pkt {
197197
/* Get Version ID */
198198
struct ncsi_rsp_gvi_pkt {
199199
struct ncsi_rsp_pkt_hdr rsp; /* Response header */
200-
__be32 ncsi_version; /* NCSI version */
200+
unsigned char major; /* NCSI version major */
201+
unsigned char minor; /* NCSI version minor */
202+
unsigned char update; /* NCSI version update */
203+
unsigned char alpha1; /* NCSI version alpha1 */
201204
unsigned char reserved[3]; /* Reserved */
202-
unsigned char alpha2; /* NCSI version */
205+
unsigned char alpha2; /* NCSI version alpha2 */
203206
unsigned char fw_name[12]; /* f/w name string */
204207
__be32 fw_version; /* f/w version */
205208
__be16 pci_ids[4]; /* PCI IDs */
@@ -335,6 +338,14 @@ struct ncsi_rsp_gpuuid_pkt {
335338
__be32 checksum;
336339
};
337340

341+
/* Get MC MAC Address */
342+
struct ncsi_rsp_gmcma_pkt {
343+
struct ncsi_rsp_pkt_hdr rsp;
344+
unsigned char address_count;
345+
unsigned char reserved[3];
346+
unsigned char addresses[][ETH_ALEN];
347+
};
348+
338349
/* AEN: Link State Change */
339350
struct ncsi_aen_lsc_pkt {
340351
struct ncsi_aen_pkt_hdr aen; /* AEN header */
@@ -395,6 +406,7 @@ struct ncsi_aen_hncdsc_pkt {
395406
#define NCSI_PKT_CMD_GPUUID 0x52 /* Get package UUID */
396407
#define NCSI_PKT_CMD_QPNPR 0x56 /* Query Pending NC PLDM request */
397408
#define NCSI_PKT_CMD_SNPR 0x57 /* Send NC PLDM Reply */
409+
#define NCSI_PKT_CMD_GMCMA 0x58 /* Get MC MAC Address */
398410

399411

400412
/* NCSI packet responses */
@@ -430,6 +442,7 @@ struct ncsi_aen_hncdsc_pkt {
430442
#define NCSI_PKT_RSP_GPUUID (NCSI_PKT_CMD_GPUUID + 0x80)
431443
#define NCSI_PKT_RSP_QPNPR (NCSI_PKT_CMD_QPNPR + 0x80)
432444
#define NCSI_PKT_RSP_SNPR (NCSI_PKT_CMD_SNPR + 0x80)
445+
#define NCSI_PKT_RSP_GMCMA (NCSI_PKT_CMD_GMCMA + 0x80)
433446

434447
/* NCSI response code/reason */
435448
#define NCSI_PKT_RSP_C_COMPLETED 0x0000 /* Command Completed */

net/ncsi/ncsi-rsp.c

+64-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@
1919
#include "ncsi-pkt.h"
2020
#include "ncsi-netlink.h"
2121

22+
/* Nibbles within [0xA, 0xF] add zero "0" to the returned value.
23+
* Optional fields (encoded as 0xFF) will default to zero.
24+
*/
25+
static u8 decode_bcd_u8(u8 x)
26+
{
27+
int lo = x & 0xF;
28+
int hi = x >> 4;
29+
30+
lo = lo < 0xA ? lo : 0;
31+
hi = hi < 0xA ? hi : 0;
32+
return lo + hi * 10;
33+
}
34+
2235
static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
2336
unsigned short payload)
2437
{
@@ -755,9 +768,18 @@ static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
755768
if (!nc)
756769
return -ENODEV;
757770

758-
/* Update to channel's version info */
771+
/* Update channel's version info
772+
*
773+
* Major, minor, and update fields are supposed to be
774+
* unsigned integers encoded as packed BCD.
775+
*
776+
* Alpha1 and alpha2 are ISO/IEC 8859-1 characters.
777+
*/
759778
ncv = &nc->version;
760-
ncv->version = ntohl(rsp->ncsi_version);
779+
ncv->major = decode_bcd_u8(rsp->major);
780+
ncv->minor = decode_bcd_u8(rsp->minor);
781+
ncv->update = decode_bcd_u8(rsp->update);
782+
ncv->alpha1 = rsp->alpha1;
761783
ncv->alpha2 = rsp->alpha2;
762784
memcpy(ncv->fw_name, rsp->fw_name, 12);
763785
ncv->fw_version = ntohl(rsp->fw_version);
@@ -1069,6 +1091,44 @@ static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
10691091
return ret;
10701092
}
10711093

1094+
static int ncsi_rsp_handler_gmcma(struct ncsi_request *nr)
1095+
{
1096+
struct ncsi_dev_priv *ndp = nr->ndp;
1097+
struct net_device *ndev = ndp->ndev.dev;
1098+
struct ncsi_rsp_gmcma_pkt *rsp;
1099+
struct sockaddr saddr;
1100+
int ret = -1;
1101+
int i;
1102+
1103+
rsp = (struct ncsi_rsp_gmcma_pkt *)skb_network_header(nr->rsp);
1104+
saddr.sa_family = ndev->type;
1105+
ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
1106+
1107+
netdev_info(ndev, "NCSI: Received %d provisioned MAC addresses\n",
1108+
rsp->address_count);
1109+
for (i = 0; i < rsp->address_count; i++) {
1110+
netdev_info(ndev, "NCSI: MAC address %d: %02x:%02x:%02x:%02x:%02x:%02x\n",
1111+
i, rsp->addresses[i][0], rsp->addresses[i][1],
1112+
rsp->addresses[i][2], rsp->addresses[i][3],
1113+
rsp->addresses[i][4], rsp->addresses[i][5]);
1114+
}
1115+
1116+
for (i = 0; i < rsp->address_count; i++) {
1117+
memcpy(saddr.sa_data, &rsp->addresses[i], ETH_ALEN);
1118+
ret = ndev->netdev_ops->ndo_set_mac_address(ndev, &saddr);
1119+
if (ret < 0) {
1120+
netdev_warn(ndev, "NCSI: Unable to assign %pM to device\n",
1121+
saddr.sa_data);
1122+
continue;
1123+
}
1124+
netdev_warn(ndev, "NCSI: Set MAC address to %pM\n", saddr.sa_data);
1125+
break;
1126+
}
1127+
1128+
ndp->gma_flag = ret == 0;
1129+
return ret;
1130+
}
1131+
10721132
static struct ncsi_rsp_handler {
10731133
unsigned char type;
10741134
int payload;
@@ -1105,7 +1165,8 @@ static struct ncsi_rsp_handler {
11051165
{ NCSI_PKT_RSP_PLDM, -1, ncsi_rsp_handler_pldm },
11061166
{ NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid },
11071167
{ NCSI_PKT_RSP_QPNPR, -1, ncsi_rsp_handler_pldm },
1108-
{ NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm }
1168+
{ NCSI_PKT_RSP_SNPR, -1, ncsi_rsp_handler_pldm },
1169+
{ NCSI_PKT_RSP_GMCMA, -1, ncsi_rsp_handler_gmcma },
11091170
};
11101171

11111172
int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,

0 commit comments

Comments
 (0)