Message ID | 1605160181-8137-3-git-send-email-moshe@mellanox.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | Add support for DSFP transceiver type | expand |
Context | Check | Description |
---|---|---|
netdev/cover_letter | success | Link |
netdev/fixes_present | success | Link |
netdev/patch_count | success | Link |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/subject_prefix | success | Link |
netdev/source_inline | success | Was 0 now: 0 |
netdev/verify_signedoff | success | Link |
netdev/module_param | success | Was 0 now: 0 |
netdev/build_32bit | success | Errors and warnings before: 0 this patch: 0 |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/verify_fixes | success | Link |
netdev/checkpatch | warning | WARNING: line length of 82 exceeds 80 columns WARNING: line length of 91 exceeds 80 columns |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 0 this patch: 0 |
netdev/header_inline | success | Link |
netdev/stable | success | Stable not CCed |
On Thu, Nov 12, 2020 at 07:49:41AM +0200, Moshe Shemesh wrote: > From: Vladyslav Tarasiuk <vladyslavt@nvidia.com> > > DSFP is a new cable module type, which EEPROM uses memory layout > described in CMIS 4.0 document. Use corresponding standard value for > userspace ethtool to distinguish DSFP's layout from older standards. > > Add DSFP module ID in accordance to SFF-8024. > > DSFP module memory can be flat or paged, which is indicated by a > flat_mem bit. In first case, only page 00 is available, and in second - > multiple pages: 00h, 01h, 02h, 10h and 11h. You are simplifying quite a bit here, listing just these pages. When i see figure 8-1, CMIS Module Memory Map, i see many more pages, and banks of pages. The current API is getting more and more strand to support SFP EEPROMs. We really do need to think of a new API, and it seems like now is a good time to do it, in order to support these devices. Andrew
On 11/12/2020 3:13 PM, Andrew Lunn wrote: > On Thu, Nov 12, 2020 at 07:49:41AM +0200, Moshe Shemesh wrote: >> From: Vladyslav Tarasiuk <vladyslavt@nvidia.com> >> >> DSFP is a new cable module type, which EEPROM uses memory layout >> described in CMIS 4.0 document. Use corresponding standard value for >> userspace ethtool to distinguish DSFP's layout from older standards. >> >> Add DSFP module ID in accordance to SFF-8024. >> >> DSFP module memory can be flat or paged, which is indicated by a >> flat_mem bit. In first case, only page 00 is available, and in second - >> multiple pages: 00h, 01h, 02h, 10h and 11h. > You are simplifying quite a bit here, listing just these pages. When i > see figure 8-1, CMIS Module Memory Map, i see many more pages, and > banks of pages. Right, but as I understand these are the basic 5 pages which are mandatory. Supporting more than that we will need new API. > The current API is getting more and more strand to support SFP > EEPROMs. We really do need to think of a new API, and it seems like > now is a good time to do it, in order to support these devices. > > Andrew
On Thu, Nov 12, 2020 at 05:54:51PM +0200, Moshe Shemesh wrote: > > On 11/12/2020 3:13 PM, Andrew Lunn wrote: > > On Thu, Nov 12, 2020 at 07:49:41AM +0200, Moshe Shemesh wrote: > > > From: Vladyslav Tarasiuk <vladyslavt@nvidia.com> > > > > > > DSFP is a new cable module type, which EEPROM uses memory layout > > > described in CMIS 4.0 document. Use corresponding standard value for > > > userspace ethtool to distinguish DSFP's layout from older standards. > > > > > > Add DSFP module ID in accordance to SFF-8024. > > > > > > DSFP module memory can be flat or paged, which is indicated by a > > > flat_mem bit. In first case, only page 00 is available, and in second - > > > multiple pages: 00h, 01h, 02h, 10h and 11h. > > You are simplifying quite a bit here, listing just these pages. When i > > see figure 8-1, CMIS Module Memory Map, i see many more pages, and > > banks of pages. > > > Right, but as I understand these are the basic 5 pages which are mandatory. > Supporting more than that we will need new API. Hi Moshe We keep kicking this can down the road. At some point it needs to happen. Since this device is not supported at the moment, there is no ethtool support for dumping it, now does seem like a good time to start on the new API. Otherwise you are going to end up writing the ethtool code twice, or at least need to do some refactoring. Andrew
On Thu, Nov 12, 2020 at 05:54:51PM +0200, Moshe Shemesh wrote: > > On 11/12/2020 3:13 PM, Andrew Lunn wrote: > > On Thu, Nov 12, 2020 at 07:49:41AM +0200, Moshe Shemesh wrote: > > > From: Vladyslav Tarasiuk <vladyslavt@nvidia.com> > > > > > > DSFP is a new cable module type, which EEPROM uses memory layout > > > described in CMIS 4.0 document. Use corresponding standard value for > > > userspace ethtool to distinguish DSFP's layout from older standards. > > > > > > Add DSFP module ID in accordance to SFF-8024. > > > > > > DSFP module memory can be flat or paged, which is indicated by a > > > flat_mem bit. In first case, only page 00 is available, and in second - > > > multiple pages: 00h, 01h, 02h, 10h and 11h. > > You are simplifying quite a bit here, listing just these pages. When i > > see figure 8-1, CMIS Module Memory Map, i see many more pages, and > > banks of pages. > > > Right, but as I understand these are the basic 5 pages which are mandatory. > Supporting more than that we will need new API. Humm, actually, looking at the diagram again, pages 10h and 11h are banked. Is one bamk sufficient? If so, you need to document that bank zero is always returned, and make sure your firmware is doing that. We also need to be clear that tunable laser information is not available, due to this fixed layout. Andrew
On 11/13/2020 2:44 AM, Andrew Lunn wrote: > On Thu, Nov 12, 2020 at 05:54:51PM +0200, Moshe Shemesh wrote: >> On 11/12/2020 3:13 PM, Andrew Lunn wrote: >>> On Thu, Nov 12, 2020 at 07:49:41AM +0200, Moshe Shemesh wrote: >>>> From: Vladyslav Tarasiuk <vladyslavt@nvidia.com> >>>> >>>> DSFP is a new cable module type, which EEPROM uses memory layout >>>> described in CMIS 4.0 document. Use corresponding standard value for >>>> userspace ethtool to distinguish DSFP's layout from older standards. >>>> >>>> Add DSFP module ID in accordance to SFF-8024. >>>> >>>> DSFP module memory can be flat or paged, which is indicated by a >>>> flat_mem bit. In first case, only page 00 is available, and in second - >>>> multiple pages: 00h, 01h, 02h, 10h and 11h. >>> You are simplifying quite a bit here, listing just these pages. When i >>> see figure 8-1, CMIS Module Memory Map, i see many more pages, and >>> banks of pages. >> >> Right, but as I understand these are the basic 5 pages which are mandatory. >> Supporting more than that we will need new API. > Humm, actually, looking at the diagram again, pages 10h and 11h are > banked. Is one bamk sufficient? If so, you need to document that bank > zero is always returned, and make sure your firmware is doing that. > > We also need to be clear that tunable laser information is not > available, due to this fixed layout. Pages 10h and 11h are banked, but the mandatory data for active transceivers is in bank 0. I will document it in the commit. There are more banked pages, but they are all optional. Also pages 03h and 04h are optional. I am looking to support here the mandatory part. For supporting the optional pages we will need to change API. > Andrew
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c index 42e61dc28ead..e6e80f1b0e94 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c @@ -1659,8 +1659,8 @@ static int mlx5e_get_module_info(struct net_device *netdev, int size_read = 0; u8 data[4] = {0}; - size_read = mlx5_query_module_eeprom(dev, 0, 2, data); - if (size_read < 2) + size_read = mlx5_query_module_eeprom(dev, 0, 3, data); + if (size_read < 3) return -EIO; /* data[0] = identifier byte */ @@ -1680,6 +1680,14 @@ static int mlx5e_get_module_info(struct net_device *netdev, modinfo->eeprom_len = ETH_MODULE_SFF_8436_MAX_LEN; } break; + case MLX5_MODULE_ID_DSFP: + modinfo->type = ETH_MODULE_CMIS_4; + /* check flat_mem bit, zero indicates paged memory */ + if (data[2] & 0x80) + modinfo->eeprom_len = ETH_MODULE_CMIS_4_LEN; + else + modinfo->eeprom_len = ETH_MODULE_CMIS_4_MAX_LEN; + break; case MLX5_MODULE_ID_SFP: modinfo->type = ETH_MODULE_SFF_8472; modinfo->eeprom_len = ETH_MODULE_SFF_8472_LEN; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c index 4bb219565c58..df8e3d024479 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c @@ -311,13 +311,9 @@ static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num, return 0; } -static int mlx5_qsfp_eeprom_page(u16 offset) +static int mlx5_eeprom_high_page_num(u16 offset) { - if (offset < MLX5_EEPROM_PAGE_LENGTH) - /* Addresses between 0-255 - page 00 */ - return 0; - - /* Addresses between 256 - 639 belongs to pages 01, 02 and 03 + /* Addresses 256 and higher belong to pages 01, 02, etc. * For example, offset = 400 belongs to page 02: * 1 + ((400 - 256)/128) = 2 */ @@ -325,6 +321,16 @@ static int mlx5_qsfp_eeprom_page(u16 offset) MLX5_EEPROM_HIGH_PAGE_LENGTH); } +static int mlx5_qsfp_eeprom_page(u16 offset) +{ + if (offset < MLX5_EEPROM_PAGE_LENGTH) + /* Addresses between 0-255 - page 00 */ + return 0; + + /* Addresses between 256 - 639 belong to pages 01, 02 and 03 */ + return mlx5_eeprom_high_page_num(offset); +} + static int mlx5_qsfp_eeprom_high_page_offset(int page_num) { if (!page_num) /* Page 0 always start from low page */ @@ -341,6 +347,37 @@ static void mlx5_qsfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offse *offset -= mlx5_qsfp_eeprom_high_page_offset(*page_num); } +static int mlx5_dsfp_eeprom_high_page_offset(int page_num) +{ + if (!page_num) + return 0; + + return (page_num < 0x10 ? page_num : page_num - 13) * MLX5_EEPROM_HIGH_PAGE_LENGTH; +} + +static int mlx5_dsfp_eeprom_page(u16 offset) +{ + if (offset < MLX5_EEPROM_PAGE_LENGTH) + return 0; + + if (offset < MLX5_EEPROM_PAGE_LENGTH + (MLX5_EEPROM_HIGH_PAGE_LENGTH * 2)) + /* Addresses 0 - 511 - pages 00, 01 and 02 */ + return mlx5_eeprom_high_page_num(offset); + + /* Offsets 512 - 767 belong to pages 10h and 11h. + * For example, offset = 700 belongs to page 11: + * 13 + 1 + ((700 - 256) / 128) = 17 = 0x11 + */ + return 13 + mlx5_eeprom_high_page_num(offset); +} + +static void mlx5_dsfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offset) +{ + *i2c_addr = MLX5_I2C_ADDR_LOW; + *page_num = mlx5_dsfp_eeprom_page(*offset); + *offset -= mlx5_dsfp_eeprom_high_page_offset(*page_num); +} + static void mlx5_sfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offset) { *i2c_addr = MLX5_I2C_ADDR_LOW; @@ -380,6 +417,9 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, case MLX5_MODULE_ID_QSFP28: mlx5_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); break; + case MLX5_MODULE_ID_DSFP: + mlx5_dsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); + break; default: mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id); return -EINVAL; diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h index 23edd2db4803..ad4b2e778d46 100644 --- a/include/linux/mlx5/port.h +++ b/include/linux/mlx5/port.h @@ -45,6 +45,7 @@ enum mlx5_module_id { MLX5_MODULE_ID_QSFP = 0xC, MLX5_MODULE_ID_QSFP_PLUS = 0xD, MLX5_MODULE_ID_QSFP28 = 0x11, + MLX5_MODULE_ID_DSFP = 0x1B, }; enum mlx5_an_status {