1 #if ZDCONF_LP_SUPPORT == 1
5 static struct lp_queue lp_q_sending
;
6 static struct lp_queue lp_q_empty
;
7 static struct lp_queue lp_q_half
;
8 static struct lp_desc lp_bucket
[LP_BUCKETS
];
9 static spinlock_t lp_spinlock
;
10 static U32 lp_spinlock_flag
;
11 static U32 varLP_MAX_PKTS_IN_BUCKET
= LP_MAX_PKTS_IN_BUCKET
;
12 //static U32 varLP_MAX_SIZE_IN_BUCKET = LP_MAX_SIZE_IN_BUCKET;
13 static U32 varLP_TIMEOUT
= LP_TIMEOUT
;
14 static U16 LP_MAX_SIZE_IN_BUCKET
[]= { 3839,1792 };
21 U32 LP_CNT_PERIOD_POP_SUCC
;
22 U32 LP_CNT_PERIOD_POP_FAIL
;
23 U32 LP_CNT_LAST_NEW_BUCK_IDX
;
24 U32 LP_CNT_LAST_LATENCY
;
28 if(!in_irq())spin_lock_irqsave(&lp_spinlock
, lp_spinlock_flag
);
32 if(!in_irq())spin_unlock_irqrestore(&lp_spinlock
, lp_spinlock_flag
);
34 void setLP_MAX_PKTS_IN_BUCKET(U32 pkts
)
37 varLP_MAX_PKTS_IN_BUCKET
= pkts
;
40 void setLP_TIMEOUT(U32 uSec
)
47 static struct lp_desc
* LP_pop_lp_desc(struct lp_queue
*lpq
)
49 struct lp_desc
*element
;
52 printk("LP_pop_lp_desc has NULL argument\n");
55 if(lpq
->first
== NULL
)
60 lpq
->first
= element
->next
;
61 if(NULL
== lpq
->first
) lpq
->last
= NULL
;
64 if(lpq
->count
< 0) printk("!!!!!!!! lpq->count < 0\n");
67 static struct lp_desc
* LP_midpop_lp_desc(struct lp_queue
*lpq
, struct lp_desc
*desc
)
69 struct lp_desc
*element
;
70 struct lp_desc
*last_desc
= NULL
;
72 if(lpq
== NULL
|| desc
== NULL
)
74 printk("LP_midpop_lp_desc has NULL argument\n");
77 if(lpq
->first
== NULL
)
86 printk("infinite loop occurs in %s\n", __FUNCTION__
);
93 if(element
== lpq
->last
) lpq
->last
= last_desc
;
94 if(!last_desc
) //desc is lpq->first
96 lpq
->first
= element
->next
;
99 last_desc
->next
= element
->next
;
101 element
->next
= NULL
;
105 element
= element
->next
;
110 static void LP_push_lp_desc(struct lp_queue
*lpq
, struct lp_desc
*desc
)
112 struct lp_desc
*element
;
113 if(lpq
== NULL
|| desc
== NULL
)
115 printk("LP_push_lp_desc has NULL argument\n");
118 if(lpq
->first
== NULL
)
128 element
->next
= desc
;
133 static struct lp_desc
* LP_first_lp_desc(struct lp_queue
*lpq
)
137 printk("LP_push_lp_desc has NULL argument\n");
143 int LP_totalReadyLen(U32 NOW) {
145 for(i=0;i<LP_BUCKETS;i++) {
146 if(lp_bucket[i].sending == 1) continue;
147 if(lp_bucket[i].pktCnt == 0) continue;
148 if((lp_bucket[i].pktCnt >= varLP_MAX_PKTS_IN_BUCKET) ||
149 (lp_bucket[i].pktSize > varLP_MAX_SIZE_IN_BUCKET*8/10) ||
150 ((NOW - lp_bucket[i].createTime) >= varLP_TIMEOUT ))
152 total+= lp_bucket[i].pktSize;
159 void lp_recycle_tx_bucket(struct lp_desc
* bucket
)
164 printk("Why do you recycle NULL bucket\n");
168 if(!LP_midpop_lp_desc(&lp_q_sending
, bucket
))
170 printk("%s, bucket doesn't exists\n", __FUNCTION__
);
172 LP_push_lp_desc(&lp_q_empty
, bucket
);
177 int pushPkt(fragInfo_t
*pkt
, BOOLEAN LenType
, U32 NOW
)
180 struct lp_desc
*desc
;
184 printk("LenType != 0 or 1, Set it as 1\n");
188 desc
= LP_first_lp_desc(&lp_q_half
);
191 if(loopCheck
++ > 100)
193 printk("infinite loop occurs in %s\n", __FUNCTION__
);
198 if(desc
->sending
== 1 ) {
199 printk("Half is sending !?\n");
203 if(desc
->pktCnt
> 0 && desc
->pktCnt
< LP_MAX_PKTS_IN_BUCKET
&& desc
->pktSize
+pkt
->bodyLen
[0] < LP_MAX_SIZE_IN_BUCKET
[LenType
])
205 if(memcmp(desc
->pkt
[0].EthHdr
, pkt
->EthHdr
, ETH_ALEN
) == 0)
207 //printk("Put packet in existing bucket\n ");
208 memcpy(&desc
->pkt
[desc
->pktCnt
],pkt
,sizeof(fragInfo_t
));
210 desc
->pktSize
+= pkt
->bodyLen
[0];
222 //printk("Create a new bucket\n");
223 //LP_CNT_LAST_NEW_BUCK_IDX = freeBucket;
224 desc
= LP_pop_lp_desc(&lp_q_empty
);
227 printk("We are out of lp_q_empty\n");
231 memcpy(&desc
->pkt
[0],pkt
,sizeof(fragInfo_t
));
233 desc
->pktSize
= pkt
->bodyLen
[0];
234 desc
->createTime
= NOW
;
235 LP_push_lp_desc(&lp_q_half
, desc
);
242 struct lp_desc
*popPkt(BOOLEAN ANYONE
, BOOLEAN LenType
, U32 NOW
)
244 struct lp_desc
*timeoutBucket
=NULL
;
245 struct lp_desc
*desc
;
249 printk("LenType != 0 or 1, Set it as 1\n");
254 desc
= LP_first_lp_desc(&lp_q_half
);
255 if(NULL
== desc
) return NULL
;
258 if(loopCheck
++ > 100)
260 printk("infinite loop occurs in %s\n", __FUNCTION__
);
265 if(desc
->sending
== 1) {
266 printk("Wow ~~~ lp_q_half has a sending one\n");
270 if(desc
->pktSize
> LP_MAX_SIZE_IN_BUCKET
[LenType
]*8/10) {
271 //printk("popPkt an exceed Size LP : %d\n", i);
273 if(!LP_midpop_lp_desc(&lp_q_half
, desc
))
274 printk("What !? midpop is NULL ?\n");
275 LP_push_lp_desc(&lp_q_sending
, desc
);
277 LP_CNT_LAST_LATENCY
= NOW
- desc
->createTime
;
280 else if(desc
->pktCnt
>= varLP_MAX_PKTS_IN_BUCKET
) {
281 //printk("popPkt an Full LP : %d\n", i);
283 if(!LP_midpop_lp_desc(&lp_q_half
, desc
))
284 printk("What !? midpop is NULL ?\n");
285 LP_push_lp_desc(&lp_q_sending
, desc
);
287 LP_CNT_LAST_LATENCY
= NOW
- desc
->createTime
;
290 if((NOW
- desc
->createTime
) >= varLP_TIMEOUT
) {
291 if(desc
->pktCnt
> 0) {
292 //printk("Level 2\n");
293 timeoutBucket
= desc
;
296 else if(ANYONE
&& desc
->pktCnt
> 0) {
298 if(!LP_midpop_lp_desc(&lp_q_half
, desc
))
299 printk("What !? midpop is NULL ?\n");
300 LP_push_lp_desc(&lp_q_sending
, desc
);
303 LP_CNT_LAST_LATENCY
= NOW
- desc
->createTime
;
309 //printk("popPkt an timeout LP : %d\n", timeoutBucket);
310 timeoutBucket
->sending
= 1;
311 if(!LP_midpop_lp_desc(&lp_q_half
, timeoutBucket
))
312 printk("What !? midpop is NULL ?\n");
313 LP_push_lp_desc(&lp_q_sending
, timeoutBucket
);
316 LP_CNT_LAST_LATENCY
= NOW
- timeoutBucket
->createTime
;
317 return timeoutBucket
;
324 printk(KERN_ERR
"LP_CNT_PUSH_SUCC:%ld\n",LP_CNT_PUSH_SUCC
);
325 printk(KERN_ERR
"LP_CNT_PUSH_FAIL:%ld\n",LP_CNT_PUSH_FAIL
);
326 printk(KERN_ERR
"LP_CNT_POP_SUCC:%ld\n",LP_CNT_POP_SUCC
);
327 printk(KERN_ERR
"LP_CNT_POP_FAIL:%ld\n",LP_CNT_POP_FAIL
);
328 printk(KERN_ERR
"LP_CNT_PERIOD_POP_SUCC:%ld\n",LP_CNT_PERIOD_POP_SUCC
);
329 printk(KERN_ERR
"LP_CNT_PERIOD_POP_FAIL:%ld\n",LP_CNT_PERIOD_POP_FAIL
);
330 printk(KERN_ERR
"LP_CNT_LAST_NEW_BUCK_IDX:%ld\n",LP_CNT_LAST_NEW_BUCK_IDX
);
331 printk(KERN_ERR
"LP_CNT_LAST_LATENCY:%ld\n", LP_CNT_LAST_LATENCY
);
332 printk(KERN_ERR
"lp_q_empty cnt : %ld\n", lp_q_empty
.count
);
333 printk(KERN_ERR
"lp_q_half cnt : %ld\n", lp_q_half
.count
);
334 printk(KERN_ERR
"lp_q_sending cnt : %ld\n", lp_q_sending
.count
);
339 memset(lp_bucket
,0,sizeof(struct lp_desc
)* LP_BUCKETS
);
340 spin_lock_init(&lp_spinlock
);
341 lp_q_sending
.first
= NULL
;
342 lp_q_sending
.count
= 0;
343 lp_q_sending
.last
= NULL
;
345 lp_q_empty
.first
= NULL
;
346 lp_q_empty
.last
= NULL
;
347 lp_q_empty
.count
= 0;
349 lp_q_half
.first
= NULL
;
350 lp_q_half
.last
= NULL
;
353 for(i
=0;i
<LP_BUCKETS
;i
++)
354 LP_push_lp_desc(&lp_q_empty
, &lp_bucket
[i
]);
355 LP_CNT_PUSH_SUCC
= 0;
356 LP_CNT_PUSH_FAIL
= 0;
359 LP_CNT_PERIOD_POP_SUCC
= 0;
360 LP_CNT_PERIOD_POP_FAIL
= 0;
361 LP_CNT_LAST_NEW_BUCK_IDX
= 0;
362 LP_CNT_LAST_LATENCY
= 0;