GLDv3 が実装する機能メカニズムでは、GLDv3 ドライバでサポートされている機能をフレームワークで照会して有効化できます。機能を報告するには mc_getcapab(9E) エントリポイントを使用します。機能がドライバによってサポートされている場合は、機能固有のエントリポイントやフラグなど、その機能についての情報を mc_getcapab() を通して渡します。mc_getcapab() エントリポイントへのポインタを mac_callback 構造体で渡します。mac_callbacks 構造体の詳細は、GLDv3 MAC Registration Data Structuresを参照してください。
boolean_t mc_getcapab(void *driver_handle, mac_capab_t cap, void *cap_data);
cap 引数は、照会する機能のタイプを指定します。cap に指定できる値は MAC_CAPAB_HCKSUM (ハードウェアチェックサムオフロード)、MAC_CAPAB_LSO (ラージセグメントオフロード)、または MAC_CAPAB_RINGS です。機能データをフレームワークに返すには、cap_data 引数を使用します。
ドライバが cap の機能をサポートする場合、mc_getcapab() エントリポイントは B_TRUE を返す必要があります。ドライバが cap の機能をサポートしない場合、mc_getcapab() は B_FALSE を返す必要があります。
使用例 19-5 mc_getcapab() エントリポイントstatic boolean_t xx_m_getcapab(void *arg, mac_capab_t cap, void *cap_data) { switch (cap) { case MAC_CAPAB_HCKSUM: { uint32_t *txflags = cap_data; *txflags = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM; break; } case MAC_CAPAB_LSO: { /* ... */ break; } case MAC_CAPAB_RINGS: { /* ... */ break; } default: return (B_FALSE); } return (B_TRUE); }
次のセクションからは、サポートされている機能と、対応する機能ごとに返されるデータについて説明します。
送信ハードウェアリングと受信ハードウェアリングはどちらも DMA チャネルであり、デバイスドライバはこれらを公開できます。リングはリンググループに関連付けられます。受信リンググループには 1 つ以上の MAC アドレスが関連付けられますが、ある受信グループに関連付けられた MAC アドレスのいずれかに一致するネットワークトラフィックはすべて、そのグループのいずれかのリング経由で NIC から配信される必要があります。受信リンググループへのトラフィックの配信は、ハードウェアのレイヤー 2 分類によって可能になります。
受信リングとリンググループとのマッピングは動的または静的に行うことができます。動的リンググループでは、フレームワークからのリクエストに応じてグループ間でリングを移動できるため、グループのサイズを動的に縮小または拡大できます。一方、静的リンググループでは、リングは静的にグループに割り当てられ、その割り当てを変更することはできません。
受信グループに複数のリングが含まれている場合、NIC は、RSS (Receive Side Scaling) などのハッシュメカニズムを使ってそれらのリング間にトラフィックを分散させることで、複数の接続がそれぞれ異なるリングに割り当てられるようにする必要があります。
受信グループのどれか 1 つ (通常はインデックス 0 にある最初のグループ) をデフォルトグループとして指定する必要があります。この受信グループには次の特性が割り当てられます。
リングを少なくとも 1 つ持つべきです。
NIC のプライマリ MAC クライアントに割り当てられます。プライマリ MAC クライアントには NIC のプライマリ MAC アドレスが割り当てられ、通常は IP になります。
ネットワークから受信されたすべてのマルチキャストおよびブロードキャストトラフィックを受信するために使用する必要があります。
NIC がプロミスキュアスモードになっている場合、デフォルト以外の受信グループに割り当てられた MAC アドレスに一致しないトラフィックをすべて、これを使って受信する必要があります。
受信リングや受信リンググループのハードウェア実装について注意すべき点を次に示します。
複数の受信リングが実装されているがレイヤー 2 分類はサポートされていない場合、ハードウェアは、すべてのリングが属する単一の受信リンググループをフレームワークに公開すべきです。
レイヤー 2 ハードウェア分類は実装されているが RSS はサポートされていない場合、ハードウェアは、それぞれ 1 つのリングを含む受信グループを複数個登録すべきです。
レイヤー 2 ハードウェア分類と RSS の両方が実装されている場合、ハードウェアは、それぞれ 1 つ以上のリングを含む受信グループを複数個登録すべきです。
レイヤー 2 ハードウェア分類も RSS も実装されていない場合、ハードウェアは、リング機能を通知しないか、あるいは単一の擬似リングとリンググループを備えたリング機能を通知すべきであり、これらを使えば、アダプタに対してトラフィックの有無を動的にポーリングできます。
リングをフレームワークに登録する際には、フレームワークからドライバへの各種呼び出しで構成されるプロセスを実行します。次の手順はその登録プロセスを説明したものです。
フレームワークは、ドライバの MAC_CAPAB_RINGS 機能のクエリーを行うために、ドライバを呼び出します。呼び出しは、送信リング用と受信リング用にそれぞれ 1 回ずつ行われます。詳細は、MAC_CAPAB_RINGS Capabilityを参照してください。
フレームワークは、1 つ前の段階で得られた mr_rget(9E) および mr_gget(9E) エントリポイントを使って特定のリングまたはリンググループに関する情報を取得します。詳細は、mr_rget(9E) およびmr_gget(9E) のマニュアルページを参照してください。
フレームワークがリングを使用する際は、1 つ前の段階で通知されたように、mgi_start(9E) エントリポイントでリンググループを開始したあと、mri_start(9E) エントリポイントを使ってリングを開始します。
これで、リングが mgi_stop(9E) および mri_stop(9E) エントリポイント経由で停止されるまで、トラフィックをリング経由で流すことができます。
フレームワークはハードウェアの送信リングと受信リングのサポートに関する情報を取得するため、cap 引数の MAC_CAPAB_RINGS を送信し、mac_capab_rings 構造体を指している cap_data フィールドに情報が返されることを想定します。
フレームワークは、mac_capab_rings(9S) 構造体を割り当て、mr_type メンバーを受信リングの場合は MAC_RING_TYPE_RX に、送信リングの場合は MAC_RING_TYPE_TX にそれぞれ設定します。すると、ドライバによって構造体 mac_capab_rings の残りのメンバーに情報が設定されます。
mac_capab_rings 構造体に定義されているフィールドは次のとおりです。
MAC_RINGS_VERSION_1 に設定する必要があります。
リングの数。
グループの数。
次の値が定義されています。
MAC_GROUP_TYPE_DYNAMIC – グループは動的です。
MAC_GROUP_TYPE_STATIC – グループは静的です。
詳細は、Rings and Ring Groups Layer–2 Classificationを参照してください。
リンググループの詳細情報を取得するドライバエントリポイント。詳細は、mr_gget() Entry Pointを参照してください。
リングの詳細情報を取得するドライバエントリポイント。詳細は、mr_rget() Entry Pointを参照してください。
リングをグループに追加するドライバエントリポイント。mr_gaddring(9E) を参照してください。
グループからリングを削除するドライバエントリポイント。mr_gremring(9E) を参照してください。
mr_gnum パラメータに示されたグループ数に対応する有効なグループインデックスごとに、mr_gget(9E) エントリポイントがフレームワークによって呼び出されます。詳細は、mr_gget(9E) を参照してください。mr_gget() を呼び出すと、ドライバによって mac_group_info 構造体にグループ情報が返されます。構造体自体はフレームワークによって事前に割り当てられ、構造体の設定はドライバによって行われます。
mac_group_info 構造体に定義されているフィールドは次のとおりです。
後続のグループエントリポイント呼び出し時にフレームワークによって使用される不透明なドライバグループハンドル。
グループ内のリング数。
グループフラグ MAC_GROUP_DEFAULT は、そのグループがデフォルトグループであることを示します。詳細は、Rings and Ring Groups Layer–2 Classificationを参照してください。
グループ開始エントリポイント。
グループ停止エントリポイント。
ユニキャスト MAC アドレス追加エントリポイント。
ユニキャスト MAC アドレス削除エントリポイント。
ハードウェアの VLAN フィルタリング、タグ付け、および VLAN タグのストリップを追加するエントリポイント。
ハードウェアの VLAN フィルタリング、タグ付け、および VLAN タグのストリップを削除するエントリポイント。
RX グループ MTU 設定エントリポイント
グループの SR-IOV 情報を取得するエントリポイント。詳細は、Ring Groups and SR-IOVを参照してください。
詳細は、mac_group_info(9S) およびmac_group_info(9E) を参照してください。
これは、NIC によって許可される必要のある、送信用および受信用の VLAN ID を定義します。つまり、構成されたリストに含まれていないタグ付きパケットはすべてドロップされます。
MAC_GROUP_VLAN_TRANSPARENT_ENABLE フラグが設定されていた場合、これは、その特定の VLAN ID のハードウェア VLAN タグ付けやストリップの有効化も行います。
MAC_CAPAB_RINGS 呼び出しで通知された mr_gnum と mr_rnum にそれぞれ示されたグループ数とリング数に対応する有効なグループインデックスおよびリングインデックスごとに、mr_rget(9E) エントリポイントがフレームワークによって呼び出されます。詳細は、mr_rget(9E) を参照してください。
mr_rget() 呼び出しが完了すると、ドライバによって mac_ring_info 構造体にリング情報が返されます。構造体はフレームワークによって事前に割り当てられ、構造体の設定はドライバによって行われます。
mac_ring_info 構造体に定義されているフィールドは次のとおりです。
後続のリングエントリポイント呼び出し時にフレームワークによって使用される不透明なドライバグループハンドル。
リング開始エントリポイント。
リング停止エントリポイント
リング統計エントリポイント。詳細は、GLDv3 Network Statisticsを参照してください。
リング送信エントリポイント。詳細は、Transmit Data Pathを参照してください。
リングポーリングエントリポイント。詳細は、Receive Data Path を参照してください。
このリングの割り込みに関連付けられた DDI 割り込みハンドル。
RX リングの割り込みを有効にします。詳細は、Receive Data Pathを参照してください。
RX リングの割り込みを無効にします。詳細は、Receive Data Path を参照してください。
詳細は、mac_group_info(9S) とmac_ring_info (9S) のマニュアルページを参照してください。
SR-IOV に対応したデバイスドライバが、自身が SR-IOV に対応していることを MAC_CAPAB_RINGS 機能を使ってフレームワークに通知するには、mgi_getsriov_info(9E) グループエントリポイントを実装します。このエントリポイントの実装は、PF ドライバが担当します。
mgi_getsriov_info(9E) を呼び出すと、ドライバによって mac_sriov_info 構造体に SR-IOV 情報が返されます。構造体はフレームワークによって事前に割り当てられ、構造体の設定はドライバによって行われます。
PF (物理機能) ドライバインスタンスは、VF (仮想機能) と同じ数の送信および受信リンググループを登録します。PF ドライバによって通知されるこれらのリンググループは特殊なもので、VF の管理に使用されます。これらのリンググループ内をデータが通過することは一切ありません。これらは、ユニキャスト MAC アドレスの構成、MTU の設定、VLAN フィルタの追加、VLAN フィルタの削除、VLAN ハードウェアの削除、および VF の VLAN タグ付けやストリップの実行を行うために使用されます。
PF ドライバによって設定される msi_vf_index 構造体メンバーには、リンググループに対応する VF インデックスが設定されます。これは、デバイスドライバが pci_plist_getvf(9F) 関数を呼び出す際に使用するのと同じインデックスです。
SR-IOV ドライバの詳細については、Chapter 21, SR-IOV Driversを参照してください。
ハードウェアチェックサムオフロードのサポートについてのデータを取得するために、フレームワークは cap 引数で MAC_CAPAB_HCKSUM を送信します。Hardware Checksum Offload Capability Informationを参照してください。
ハードウェアによるチェックサム計算が有効なときに、チェックサムオフロードのメタデータを照会したり、パケット単位でのハードウェアによるチェックサム計算のメタデータを取得したりするには、mac_hcksum_get(9F) を使用します。The mac_hcksum_get() Function Flagsを参照してください。
チェックサムオフロードのメタデータを設定するには、mac_hcksum_set (9F) を使用します。The mac_hcksum_set() Function Flagsを参照してください。
詳細は、Hardware Checksumming: HardwareおよびHardware Checksumming: MAC Layerを参照してください。
MAC_CAPAB_HCKSUM 機能についての情報をフレームワークに渡すために、ドライバは uint32_t を指し示す cap_data で次のフラグの組み合わせを設定する必要があります。これらのフラグは、アウトバウンドパケットに対してドライバが実行できるハードウェアチェックサムオフロードのレベルを示します。
1 の補数による部分チェックサム機能
IPv4 パケット対象の 1 の補数による完全チェックサム機能
IPv6 パケット対象の 1 の補数による完全チェックサム機能
IPv4 ヘッダーのチェックサムオフロード機能
mac_hcksum_get() の flags 引数は次の値の組み合わせです。
このパケットの完全チェックサムを計算します。
完全チェックサムがハードウェアで検証済みであり、正確です。
mac_hcksum_get() に渡されるほかのパラメータに基づいて、1 の補数による部分チェックサムを計算します。HCK_PARTIALCKSUM は HCK_FULLCKSUM と相互排他です。
IP ヘッダーのチェックサムを計算します。
IP ヘッダーのチェックサムはハードウェアで検証済みであり、正確です。
mac_hcksum_set() の flags 引数は次の値の組み合わせです。
完全チェックサムが計算され、value 引数を介して渡されました。
完全チェックサムがハードウェアで検証済みであり、正確です。
部分チェックサムが計算され、value 引数を介して渡されました。HCK_PARTIALCKSUM は HCK_FULLCKSUM と相互排他です。
IP ヘッダーのチェックサムが計算され、value 引数を介して渡されました。
IP ヘッダーのチェックサムはハードウェアで検証済みであり、正確です。
ラージセグメント (送信) オフロードのサポートを照会するために、フレームワークは cap 引数で MAC_CAPAB_LSO を送信し、mac_capab_lso(9S) 構造体を指し示す cap_data に情報が返されることを想定します。フレームワークは mac_capab_lso 構造体を割り当て、この構造体へのポインタを cap_data に渡します。mac_capab_lso 構造体は lso_basic_tcp_ipv4(9S) 構造体と lso_flags メンバーで構成されます。ドライバインスタンスが TCP/IPv4 での LSO をサポートする場合、LSO_TX_BASIC_TCP_IPV4 フラグを lso_flags に設定し、デバイスインスタンスがサポートする最大ペイロードサイズを lso_basic_tcp_ipv4 構造体の lso_max メンバーに設定します。
パケット単位での LSO のメタデータを取得するには、 mac_lso_get(9F) を使用します。このパケットに対して LSO が有効な場合、mac_lso_get() の flags 引数に HW_LSO フラグが設定されます。ラージセグメントのセグメンテーション中に使用される最大セグメントサイズ (MSS) は、mss 引数によって指示される場所を介して返されます。詳細は、Large Segment Offloadを参照してください。