|
@@ -832,6 +832,62 @@ static void intelxl_close_admin ( struct intelxl_nic *intelxl ) {
|
832
|
832
|
******************************************************************************
|
833
|
833
|
*/
|
834
|
834
|
|
|
835
|
+/**
|
|
836
|
+ * Allocate descriptor ring
|
|
837
|
+ *
|
|
838
|
+ * @v intelxl Intel device
|
|
839
|
+ * @v ring Descriptor ring
|
|
840
|
+ * @ret rc Return status code
|
|
841
|
+ */
|
|
842
|
+static int intelxl_alloc_ring ( struct intelxl_nic *intelxl,
|
|
843
|
+ struct intelxl_ring *ring ) {
|
|
844
|
+ physaddr_t address;
|
|
845
|
+ int rc;
|
|
846
|
+
|
|
847
|
+ /* Allocate descriptor ring */
|
|
848
|
+ ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN );
|
|
849
|
+ if ( ! ring->desc.raw ) {
|
|
850
|
+ rc = -ENOMEM;
|
|
851
|
+ goto err_alloc;
|
|
852
|
+ }
|
|
853
|
+ address = virt_to_bus ( ring->desc.raw );
|
|
854
|
+
|
|
855
|
+ /* Initialise descriptor ring */
|
|
856
|
+ memset ( ring->desc.raw, 0, ring->len );
|
|
857
|
+
|
|
858
|
+ /* Reset tail pointer */
|
|
859
|
+ writel ( 0, ( intelxl->regs + ring->tail ) );
|
|
860
|
+
|
|
861
|
+ /* Reset counters */
|
|
862
|
+ ring->prod = 0;
|
|
863
|
+ ring->cons = 0;
|
|
864
|
+
|
|
865
|
+ DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n",
|
|
866
|
+ intelxl, ( ring->reg + ring->tail ),
|
|
867
|
+ ( ( unsigned long long ) address ),
|
|
868
|
+ ( ( unsigned long long ) address + ring->len ) );
|
|
869
|
+
|
|
870
|
+ return 0;
|
|
871
|
+
|
|
872
|
+ free_dma ( ring->desc.raw, ring->len );
|
|
873
|
+ err_alloc:
|
|
874
|
+ return rc;
|
|
875
|
+}
|
|
876
|
+
|
|
877
|
+/**
|
|
878
|
+ * Free descriptor ring
|
|
879
|
+ *
|
|
880
|
+ * @v intelxl Intel device
|
|
881
|
+ * @v ring Descriptor ring
|
|
882
|
+ */
|
|
883
|
+static void intelxl_free_ring ( struct intelxl_nic *intelxl __unused,
|
|
884
|
+ struct intelxl_ring *ring ) {
|
|
885
|
+
|
|
886
|
+ /* Free descriptor ring */
|
|
887
|
+ free_dma ( ring->desc.raw, ring->len );
|
|
888
|
+ ring->desc.raw = NULL;
|
|
889
|
+}
|
|
890
|
+
|
835
|
891
|
/**
|
836
|
892
|
* Dump queue context (for debugging)
|
837
|
893
|
*
|
|
@@ -1100,17 +1156,8 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl,
|
1100
|
1156
|
int rc;
|
1101
|
1157
|
|
1102
|
1158
|
/* Allocate descriptor ring */
|
1103
|
|
- ring->desc.raw = malloc_dma ( ring->len, INTELXL_ALIGN );
|
1104
|
|
- if ( ! ring->desc.raw ) {
|
1105
|
|
- rc = -ENOMEM;
|
|
1159
|
+ if ( ( rc = intelxl_alloc_ring ( intelxl, ring ) ) != 0 )
|
1106
|
1160
|
goto err_alloc;
|
1107
|
|
- }
|
1108
|
|
-
|
1109
|
|
- /* Initialise descriptor ring */
|
1110
|
|
- memset ( ring->desc.raw, 0, ring->len );
|
1111
|
|
-
|
1112
|
|
- /* Reset tail pointer */
|
1113
|
|
- writel ( 0, ( intelxl->regs + ring->tail ) );
|
1114
|
1161
|
|
1115
|
1162
|
/* Program queue context */
|
1116
|
1163
|
address = virt_to_bus ( ring->desc.raw );
|
|
@@ -1121,21 +1168,12 @@ static int intelxl_create_ring ( struct intelxl_nic *intelxl,
|
1121
|
1168
|
if ( ( rc = intelxl_enable_ring ( intelxl, ring ) ) != 0 )
|
1122
|
1169
|
goto err_enable;
|
1123
|
1170
|
|
1124
|
|
- /* Reset counters */
|
1125
|
|
- ring->prod = 0;
|
1126
|
|
- ring->cons = 0;
|
1127
|
|
-
|
1128
|
|
- DBGC ( intelxl, "INTELXL %p ring %06x is at [%08llx,%08llx)\n",
|
1129
|
|
- intelxl, ( ring->reg + ring->tail ),
|
1130
|
|
- ( ( unsigned long long ) address ),
|
1131
|
|
- ( ( unsigned long long ) address + ring->len ) );
|
1132
|
|
-
|
1133
|
1171
|
return 0;
|
1134
|
1172
|
|
1135
|
1173
|
intelxl_disable_ring ( intelxl, ring );
|
1136
|
1174
|
err_enable:
|
1137
|
1175
|
err_context:
|
1138
|
|
- free_dma ( ring->desc.raw, ring->len );
|
|
1176
|
+ intelxl_free_ring ( intelxl, ring );
|
1139
|
1177
|
err_alloc:
|
1140
|
1178
|
return rc;
|
1141
|
1179
|
}
|
|
@@ -1157,8 +1195,7 @@ static void intelxl_destroy_ring ( struct intelxl_nic *intelxl,
|
1157
|
1195
|
}
|
1158
|
1196
|
|
1159
|
1197
|
/* Free descriptor ring */
|
1160
|
|
- free_dma ( ring->desc.raw, ring->len );
|
1161
|
|
- ring->desc.raw = NULL;
|
|
1198
|
+ intelxl_free_ring ( intelxl, ring );
|
1162
|
1199
|
}
|
1163
|
1200
|
|
1164
|
1201
|
/**
|
|
@@ -1211,6 +1248,22 @@ static void intelxl_refill_rx ( struct intelxl_nic *intelxl ) {
|
1211
|
1248
|
}
|
1212
|
1249
|
}
|
1213
|
1250
|
|
|
1251
|
+/**
|
|
1252
|
+ * Discard unused receive I/O buffers
|
|
1253
|
+ *
|
|
1254
|
+ * @v intelxl Intel device
|
|
1255
|
+ */
|
|
1256
|
+static void intelxl_empty_rx ( struct intelxl_nic *intelxl ) {
|
|
1257
|
+ unsigned int i;
|
|
1258
|
+
|
|
1259
|
+ /* Discard any unused receive buffers */
|
|
1260
|
+ for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) {
|
|
1261
|
+ if ( intelxl->rx_iobuf[i] )
|
|
1262
|
+ free_iob ( intelxl->rx_iobuf[i] );
|
|
1263
|
+ intelxl->rx_iobuf[i] = NULL;
|
|
1264
|
+ }
|
|
1265
|
+}
|
|
1266
|
+
|
1214
|
1267
|
/******************************************************************************
|
1215
|
1268
|
*
|
1216
|
1269
|
* Network device interface
|
|
@@ -1297,7 +1350,6 @@ static int intelxl_open ( struct net_device *netdev ) {
|
1297
|
1350
|
static void intelxl_close ( struct net_device *netdev ) {
|
1298
|
1351
|
struct intelxl_nic *intelxl = netdev->priv;
|
1299
|
1352
|
unsigned int queue;
|
1300
|
|
- unsigned int i;
|
1301
|
1353
|
|
1302
|
1354
|
/* Dump contexts (for debugging) */
|
1303
|
1355
|
intelxl_context_dump ( intelxl, INTELXL_PFCM_LANCTXCTL_TYPE_TX,
|
|
@@ -1319,11 +1371,7 @@ static void intelxl_close ( struct net_device *netdev ) {
|
1319
|
1371
|
intelxl_destroy_ring ( intelxl, &intelxl->rx );
|
1320
|
1372
|
|
1321
|
1373
|
/* Discard any unused receive buffers */
|
1322
|
|
- for ( i = 0 ; i < INTELXL_RX_NUM_DESC ; i++ ) {
|
1323
|
|
- if ( intelxl->rx_iobuf[i] )
|
1324
|
|
- free_iob ( intelxl->rx_iobuf[i] );
|
1325
|
|
- intelxl->rx_iobuf[i] = NULL;
|
1326
|
|
- }
|
|
1374
|
+ intelxl_empty_rx ( intelxl );
|
1327
|
1375
|
}
|
1328
|
1376
|
|
1329
|
1377
|
/**
|